1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2019 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2015 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "16x16_layer.h"
26 using namespace NLMISC
;
29 * Loads a 16x16Layer and returns a pointer to it. Layer is automatically allocated.
31 I16x16Layer
*I16x16Layer::load(NLMISC::IStream
&f
)
36 I16x16Layer
*layer
= NULL
;
40 case 1: layer
= new CFull16x16Layer(); break;
41 case 2: layer
= new C8Bits16x16Layer(); break;
42 case 3: layer
= new C4Bits16x16Layer(); break;
43 case 4: layer
= new C2Bits16x16Layer(); break;
44 case 5: layer
= new C1Bit16x16Layer(); break;
45 case 6: layer
= new CWhite16x16Layer(); break;
57 void I16x16Layer::save(NLMISC::IStream
&f
, I16x16Layer
*layer
)
61 if (dynamic_cast<CFull16x16Layer
*>(layer
)) type
= 1;
62 else if (dynamic_cast<C8Bits16x16Layer
*>(layer
)) type
= 2;
63 else if (dynamic_cast<C4Bits16x16Layer
*>(layer
)) type
= 3;
64 else if (dynamic_cast<C2Bits16x16Layer
*>(layer
)) type
= 4;
65 else if (dynamic_cast<C1Bit16x16Layer
*>(layer
)) type
= 5;
66 else if (dynamic_cast<CWhite16x16Layer
*>(layer
)) type
= 6;
71 else if (layer
!= NULL
)
72 nlwarning("Unknown 16x16 layer type %s, aborted", typeid(*layer
).name());
77 * Compresses a 16x16Layer. Returns a new layer if compression was successful, otherwise returns same layer.
78 * If compression was successful, previous layer is deleted.
80 I16x16Layer
*I16x16Layer::compress(I16x16Layer
*layer
, sint32 blank
)
82 CFull16x16Layer
*flayer
= dynamic_cast<CFull16x16Layer
*>(layer
);
85 nlwarning("Can't compressed layer, already compressed");
89 sint32 min
= 0x7fffffff, max
= 0x80000000;
92 map
<sint32
, uint
> count
;
94 for (i
=0; i
<16; ++i
) for (j
=0;j
<16;++j
)
96 sint32 val
= flayer
->Array
[i
][j
];
101 if (val
< min
) min
= val
;
102 if (val
> max
) max
= val
;
104 map
<sint32
, uint
>::iterator it
= count
.find(val
);
105 if (it
== count
.end())
106 count
.insert(std::pair
<sint32
, uint
>(val
, 1));
111 uint msize
= (uint
)count
.size();
116 CWhite16x16Layer
*nlayer
= new CWhite16x16Layer();
117 nlayer
->set(0, 0, min
);
123 // 1 bit 16x16 layer, 2 values
124 C1Bit16x16Layer
*nlayer
= new C1Bit16x16Layer();
125 nlayer
->Values
[0] = min
;
126 nlayer
->Values
[1] = max
;
129 nlayer
->set(i
, j
, flayer
->get(i
, j
));
131 compare(layer
, nlayer
, 0x7fffffff);
137 // 2 bits 16x16 layer, 4 values
138 C2Bits16x16Layer
*nlayer
= new C2Bits16x16Layer();
139 map
<sint32
, uint
>::iterator it
;
141 for (it
=count
.begin(); it
!=count
.end(); ++it
)
142 nlayer
->Values
[i
++] = (*it
).first
;
145 nlayer
->set(i
, j
, flayer
->get(i
, j
));
147 compare(layer
, nlayer
, 0x7fffffff);
151 else if (max
-min
< 16)
153 // 4 bits 16x16 layer, 16 values in range
154 C4Bits16x16Layer
*nlayer
= new C4Bits16x16Layer();
158 nlayer
->set(i
, j
, flayer
->get(i
, j
));
160 compare(layer
, nlayer
, 0x7fffffff);
164 else if (max
-min
< 256)
166 // 8 bits 16x16 layer, 256 values in range
167 C8Bits16x16Layer
*nlayer
= new C8Bits16x16Layer();
171 nlayer
->set(i
, j
, flayer
->get(i
, j
));
173 compare(layer
, nlayer
, 0x7fffffff);
181 bool I16x16Layer::compare(I16x16Layer
*original
, I16x16Layer
*copy
, sint32 avoid
)
189 if (original
->get(i
, j
) != avoid
&& original
->get(i
, j
) != copy
->get(i
, j
))
191 nlwarning("Different values !");