1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2019 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #ifndef NL_16X16_LAYER_H
20 #define NL_16X16_LAYER_H
22 #include "nel/misc/types_nl.h"
23 #include "nel/misc/stream.h"
25 template<typename T
, int NumObjects
>
31 TypeSize
= sizeof(T
)*8,
32 ObjectSize
= TypeSize
/NumObjects
,
33 Mask
= (1<<ObjectSize
)-1
39 CFastBitField(uint val
=0) : Field((T
)val
) {}
41 CFastBitField
&operator = (const uint
&val
) { Field
= (T
)val
; return *this; }
42 CFastBitField
&operator = (const CFastBitField
&bf
) { Field
= bf
.Field
; return *this; }
44 bool operator == (const uint
&val
) const { return Field
== (T
)val
; }
45 bool operator == (const CFastBitField
&bf
) const { return Field
== bf
.Field
; }
46 bool operator != (const uint
&val
) const { return Field
!= (T
)val
; }
47 bool operator != (const CFastBitField
&bf
) const { return Field
!= bf
.Field
; }
49 uint
get(uint i
) const
51 const uint Offset
= TypeSize
- ObjectSize
*((i
&(NumObjects
-1))+1);
52 return (Field
>> Offset
) & Mask
;
55 void set(uint i
, uint value
)
57 const uint Offset
= TypeSize
- ObjectSize
*((i
&(NumObjects
-1))+1);
58 Field
= (Field
& (~(Mask
<< Offset
))) | (value
<< Offset
);
61 void serial(NLMISC::IStream
&f
) { f
.serial(Field
); }
64 typedef CFastBitField
<uint32
, 8> T4BitField
;
65 typedef CFastBitField
<uint32
, 16> T2BitField
;
66 typedef CFastBitField
<uint16
, 16> T1BitField
;
71 * The 16x16 crunch layer interface.
72 * Used to compress 16x16 value maps in adaptive schemes
73 * \author Benjamin Legros
74 * \author Nevrax France
80 virtual ~I16x16Layer() {}
83 * Get uncompressed value at i, j where i is y-like and j is x-like
84 * Data are assumed to be stored in a c-style array like sint Array[16][16], that is accessed through Array[i][j].
85 * i and j MUST be clamped to interval [0, 16], as they might not be tested.
87 virtual sint
get(uint i
, uint j
) const = 0;
90 * Set uncompressed value at i, j where i is y-like and j is x-like
91 * Data are assumed to be stored in a c-style array like sint Array[16][16], that is accessed through Array[i][j].
92 * i and j MUST be clamped to interval [0, 16], as they might not be tested.
94 virtual void set(uint i
, uint j
, sint value
) = 0;
98 * Loads a 16x16Layer and returns a pointer to it. Layer is automatically allocated.
100 static I16x16Layer
*load(NLMISC::IStream
&f
);
103 * Saves a 16x16Layer.
105 static void save(NLMISC::IStream
&f
, I16x16Layer
*layer
);
108 * Compresses a 16x16Layer. Returns a new layer if compression was successful, otherwise returns same layer.
109 * If compression was successful, previous layer is deleted.
111 static I16x16Layer
*compress(I16x16Layer
*layer
, sint32 blank
);
116 static bool compare(I16x16Layer
*original
, I16x16Layer
*copy
, sint32 avoid
);
120 * Internal use, not to be called directly
122 virtual void serial(NLMISC::IStream
&f
) = 0;
127 * The uncompressed 16x16 layer
128 * 16*16*4 = 1024 bytes of raw data
129 * \author Benjamin Legros
130 * \author Nevrax France
133 class CFull16x16Layer
: public I16x16Layer
137 sint32 Array
[16][16];
139 CFull16x16Layer() { memset(Array
, 0, sizeof(Array
)); }
140 sint
get(uint i
, uint j
) const { nlassert(i
<16 && j
<16); return Array
[i
][j
]; }
141 void set(uint i
, uint j
, sint value
) { nlassert(i
<16 && j
<16); Array
[i
][j
] = value
; }
144 void serial(NLMISC::IStream
&f
) {
145 for (uint i
=0; i
<16; ++i
)
146 for (uint j
=0; j
<16; ++j
)
147 f
.serial(Array
[i
][j
]);
152 * The byte compressed 16x16 layer
153 * 16*16*1+4 = 260 bytes of raw data
154 * \author Benjamin Legros
155 * \author Nevrax France
158 class C8Bits16x16Layer
: public I16x16Layer
165 C8Bits16x16Layer(sint32 mean
=0) : Mean(mean
) { memset(Array
, 0, sizeof(Array
)); }
166 sint
get(uint i
, uint j
) const { nlassert(i
<16 && j
<16); return Mean
+ Array
[i
][j
]; }
167 void set(uint i
, uint j
, sint value
) { nlassert(i
<16 && j
<16); Array
[i
][j
] = (uint8
)(value
-Mean
); }
170 void serial(NLMISC::IStream
&f
)
173 for (uint i
=0; i
<16; ++i
)
174 for(uint j
=0; j
<16; ++j
)
175 f
.serial(Array
[i
][j
]);
180 * The nibble compressed 16x16 layer
181 * 16*16/2+4 = 132 bytes of raw data
182 * \author Benjamin Legros
183 * \author Nevrax France
186 class C4Bits16x16Layer
: public I16x16Layer
191 T4BitField Array
[16][2];
193 C4Bits16x16Layer(sint32 mean
=0) : Mean(mean
) { memset(Array
, 0, sizeof(Array
)); }
194 sint
get(uint i
, uint j
) const { nlassert(i
<16 && j
<16); return Mean
+ Array
[i
][j
>>3].get(j
); }
195 void set(uint i
, uint j
, sint value
) { nlassert(i
<16 && j
<16); Array
[i
][j
>>3].set(j
, (value
-Mean
)&0xf); }
198 void serial(NLMISC::IStream
&f
)
201 for (uint i
=0; i
<16; ++i
)
202 for (uint j
=0; j
<2; ++j
)
203 f
.serial(Array
[i
][j
]);
208 * The 2 bits compressed 16x16 layer
209 * The 4 values are encoded separately
210 * 32+4*4 = 48 bytes of raw data
211 * \author Benjamin Legros
212 * \author Nevrax France
215 class C2Bits16x16Layer
: public I16x16Layer
220 T2BitField Array
[16];
222 C2Bits16x16Layer(sint32 v0
=0, sint32 v1
=1, sint32 v2
=2, sint32 v3
=3) { Values
[0] = v0
; Values
[1] = v1
; Values
[2] = v2
; Values
[3] = v3
; memset(Array
, 0, sizeof(Array
)); }
223 sint
get(uint i
, uint j
) const { nlassert(i
<16 && j
<16); return Values
[Array
[i
].get(j
)]; }
224 void set(uint i
, uint j
, sint value
) { nlassert(i
<16 && j
<16); Array
[i
].set(j
, getIndex(value
)); }
227 void serial(NLMISC::IStream
&f
)
229 f
.serial(Values
[0], Values
[1], Values
[2], Values
[3]);
230 for (uint i
=0; i
<16; ++i
)
234 uint
getIndex(sint value
)
237 for (i
=0; i
<4 && Values
[i
]!=value
; ++i
) ;
243 * The 1 bit compressed 16x16 layer
244 * The 2 values are encoded separately
245 * 16+4+4 = 24 bytes of raw data
246 * \author Benjamin Legros
247 * \author Nevrax France
250 class C1Bit16x16Layer
: public I16x16Layer
255 T1BitField Array
[16];
257 C1Bit16x16Layer(sint32 v0
=0, sint32 v1
=1) { Values
[0] = v0
; Values
[1] = v1
; memset(Array
, 0, sizeof(Array
)); }
258 sint
get(uint i
, uint j
) const { nlassert(i
<16 && j
<16); return Values
[Array
[i
].get(j
)]; }
259 void set(uint i
, uint j
, sint value
) { nlassert(i
<16 && j
<16); Array
[i
].set(j
, getIndex(value
)); }
262 void serial(NLMISC::IStream
&f
)
264 f
.serial(Values
[0], Values
[1]);
265 for (uint i
=0; i
<16; ++i
)
269 uint
getIndex(sint value
) { return value
== Values
[0] ? 0 : 1; }
273 * The 1 value compressed 16x16 layer
274 * 4 bytes of raw data
275 * \author Benjamin Legros
276 * \author Nevrax France
279 class CWhite16x16Layer
: public I16x16Layer
285 CWhite16x16Layer(sint32 value
=0) : Value(value
) { }
286 sint
get(uint i
, uint j
) const { return Value
; }
287 void set(uint i
, uint j
, sint value
) { Value
= value
; }
290 void serial(NLMISC::IStream
&f
) { f
.serial(Value
); }
294 #endif // NL_16X16_LAYER_H
296 /* End of 16x16_layer.h */