Browse Source

TextureTools: check that atlasArrayPowerOfTwo() sizes are in bounds.

What, such an essential check was missing there?
pull/168/head
Vladimír Vondruš 3 years ago
parent
commit
958e5edbc2
  1. 4
      src/Magnum/TextureTools/Atlas.cpp
  2. 5
      src/Magnum/TextureTools/Atlas.h
  3. 23
      src/Magnum/TextureTools/Test/AtlasTest.cpp

4
src/Magnum/TextureTools/Atlas.cpp

@ -80,8 +80,8 @@ Containers::Pair<Int, Containers::Array<Vector3i>> atlasArrayPowerOfTwo(const Ve
Containers::Array<Vector3i> sortedSizes{NoInit, sizes.size()};
for(std::size_t i = 0; i != sizes.size(); ++i) {
const Vector2i size = sizes[i];
CORRADE_ASSERT(size.product() && size.x() == size.y() && (size & (size - Vector2i{1})).isZero(),
"TextureTools::atlasArrayPowerOfTwo(): expected size" << i << "to be a non-zero power-of-two square, got" << Debug::packed << size, {});
CORRADE_ASSERT(size.product() && size.x() == size.y() && (size & (size - Vector2i{1})).isZero() && size <= layerSize,
"TextureTools::atlasArrayPowerOfTwo(): expected size" << i << "to be a non-zero power-of-two square not larger than" << Debug::packed << layerSize << "but got" << Debug::packed << size, {});
sortedSizes[i].xy() = size;
sortedSizes[i].z() = i;

5
src/Magnum/TextureTools/Atlas.h

@ -60,8 +60,9 @@ std::vector<Range2Di> MAGNUM_TEXTURETOOLS_EXPORT atlas(const Vector2i& atlasSize
coordinate being the layer index
@m_since_latest
Both @p layerSize and all items in @p sizes are expected to be non-zero, square
and power-of-two. With such constraints the packing is optimal with no wasted
The @p layerSize is expected to be non-zero, square and power-of-two. All items
in @p sizes are expected to be non-zero, square, power-of-two and not larger
than @p layerSize. With such constraints the packing is optimal with no wasted
space in all but the last layer. Setting @p layerSize to the size of the
largest texture in the set will lead to the least wasted space in the last
layer.

23
src/Magnum/TextureTools/Test/AtlasTest.cpp

@ -70,14 +70,25 @@ const struct {
{0, 2, 7, 13, 11, 3, 4, 5, 8, 14, 1, 9, 6, 12, 10}},
};
const struct {
const char* name;
Vector2i size;
const char* message;
} ArrayPowerOfTwoWrongLayerSizeData[]{
{"non-power-of-two", {128, 127}, "{128, 127}"},
{"non-square", {128, 256}, "{128, 256}"},
{"zero", {1024, 0}, "{1024, 0}"},
};
const struct {
const char* name;
Vector2i size;
const char* message;
} ArrayPowerOfTwoWrongSizeData[]{
{"larger than size", {512, 512}, "{512, 512}"},
{"non-power-of-two", {128, 127}, "{128, 127}"},
{"non-square", {128, 256}, "{128, 256}"},
{"zero", {1024, 0}, "{1024, 0}"}
{"zero", {1024, 0}, "{1024, 0}"},
};
AtlasTest::AtlasTest() {
@ -95,8 +106,10 @@ AtlasTest::AtlasTest() {
addTests({&AtlasTest::arrayPowerOfTwoMoreLayers});
addInstancedTests({&AtlasTest::arrayPowerOfTwoWrongLayerSize,
&AtlasTest::arrayPowerOfTwoWrongSize},
addInstancedTests({&AtlasTest::arrayPowerOfTwoWrongLayerSize},
Containers::arraySize(ArrayPowerOfTwoWrongLayerSizeData));
addInstancedTests({&AtlasTest::arrayPowerOfTwoWrongSize},
Containers::arraySize(ArrayPowerOfTwoWrongSizeData));
}
@ -274,7 +287,7 @@ void AtlasTest::arrayPowerOfTwoMoreLayers() {
}
void AtlasTest::arrayPowerOfTwoWrongLayerSize() {
auto&& data = ArrayPowerOfTwoWrongSizeData[testCaseInstanceId()];
auto&& data = ArrayPowerOfTwoWrongLayerSizeData[testCaseInstanceId()];
setTestCaseDescription(data.name);
CORRADE_SKIP_IF_NO_ASSERT();
@ -298,7 +311,7 @@ void AtlasTest::arrayPowerOfTwoWrongSize() {
{128, 128},
data.size
});
CORRADE_COMPARE(out.str(), Utility::formatString("TextureTools::atlasArrayPowerOfTwo(): expected size 2 to be a non-zero power-of-two square, got {}\n", data.message));
CORRADE_COMPARE(out.str(), Utility::formatString("TextureTools::atlasArrayPowerOfTwo(): expected size 2 to be a non-zero power-of-two square not larger than {{256, 256}} but got {}\n", data.message));
}
}}}}

Loading…
Cancel
Save