@@ -1481,12 +1481,12 @@ void VTF::removeResourceInternal(Resource::Type type) {
14811481}
14821482
14831483void VTF::regenerateImageData (ImageFormat newFormat, uint16_t newWidth, uint16_t newHeight, uint8_t newMipCount, uint16_t newFrameCount, uint8_t newFaceCount, uint16_t newDepth, ImageConversion::ResizeFilter filter, float quality) {
1484- if (!newWidth) { newWidth = 1 ; }
1485- if (!newHeight) { newHeight = 1 ; }
1486- if (!newMipCount) { newMipCount = 1 ; }
1487- if (!newFrameCount) { newFrameCount = 1 ; }
1488- if (!newFaceCount) { newFaceCount = 1 ; }
1489- if (!newDepth) { newDepth = 1 ; }
1484+ if (!newWidth) newWidth = 1 ;
1485+ if (!newHeight) newHeight = 1 ;
1486+ if (!newMipCount) newMipCount = 1 ;
1487+ if (!newFrameCount) newFrameCount = 1 ;
1488+ if (!newFaceCount) newFaceCount = 1 ;
1489+ if (!newDepth) newDepth = 1 ;
14901490
14911491 if (newMipCount > 1 ) {
14921492 // Valve code doesn't like it when you have compressed mips with padding unless they're lower than 4 on a given dimension!
@@ -1512,19 +1512,38 @@ void VTF::regenerateImageData(ImageFormat newFormat, uint16_t newWidth, uint16_t
15121512 } else {
15131513 newImageData.resize (ImageFormatDetails::getDataLength (this ->format , newMipCount, newFrameCount, newFaceCount, newWidth, newHeight, newDepth));
15141514 for (int i = newMipCount - 1 ; i >= 0 ; i--) {
1515- const auto [mipWidth, mipHeight] = ImageDimensions::getMipDims (i, this ->width , this ->height );
15161515 const auto [newMipWidth, newMipHeight, newMipDepth] = ImageDimensions::getMipDims (i, newWidth, newHeight, newDepth);
1516+
1517+ int sourceMipIndex = 0 ;
1518+ for (int mip = 0 , bestScore = std::numeric_limits<int >::max (); mip < this ->mipCount ; mip++) {
1519+ const auto [mipWidth, mipHeight] = ImageDimensions::getMipDims (mip, this ->width , this ->height , false );
1520+ if (mipWidth == newMipWidth && mipHeight == newMipHeight) {
1521+ break ;
1522+ }
1523+ const auto widthDiff = static_cast <int >(mipWidth) - static_cast <int >(newMipWidth);
1524+ const auto heightDiff = static_cast <int >(mipHeight) - static_cast <int >(newMipHeight);
1525+ if (widthDiff < 0 || heightDiff < 0 ) {
1526+ continue ;
1527+ }
1528+ if (const auto score = widthDiff + heightDiff; score < bestScore) {
1529+ bestScore = score;
1530+ sourceMipIndex = mip;
1531+ }
1532+ }
1533+ const auto [sourceMipWidth, sourceMipHeight] = ImageDimensions::getMipDims (sourceMipIndex, this ->width , this ->height );
1534+
15171535 for (int j = 0 ; j < newFrameCount; j++) {
15181536 for (int k = 0 ; k < newFaceCount; k++) {
15191537 for (int l = 0 ; l < newMipDepth; l++) {
1520- if (i < this ->mipCount && j < this ->frameCount && k < faceCount && l < this ->depth ) {
1521- auto imageSpan = this ->getImageDataRaw (i, j, k, l);
1522- std::vector<std::byte> image{imageSpan.begin (), imageSpan.end ()};
1523- if (this ->width != newWidth || this ->height != newHeight) {
1524- image = ImageConversion::resizeImageData (image, this ->format , mipWidth, newMipWidth, mipHeight, newMipHeight, this ->isSRGB (), filter);
1538+ if (j < this ->frameCount && k < faceCount && l < this ->depth ) {
1539+ auto imageSpan = this ->getImageDataRaw (sourceMipIndex, j, k, l);
1540+ std::vector<std::byte> imageBacking;
1541+ if (sourceMipWidth != newMipWidth || sourceMipHeight != newMipHeight) {
1542+ imageBacking = ImageConversion::resizeImageData (imageSpan, this ->format , sourceMipWidth, newMipWidth, sourceMipHeight, newMipHeight, this ->isSRGB (), filter);
1543+ imageSpan = imageBacking;
15251544 }
1526- if (uint32_t offset, length; ImageFormatDetails::getDataPosition (offset, length, this ->format , i, newMipCount, j, newFrameCount, k, newFaceCount, newWidth, newHeight, l, newDepth) && image .size () == length) {
1527- std::memcpy (newImageData.data () + offset, image .data (), length);
1545+ if (uint32_t offset, length; ImageFormatDetails::getDataPosition (offset, length, this ->format , i, newMipCount, j, newFrameCount, k, newFaceCount, newWidth, newHeight, l, newDepth) && imageSpan .size () == length) {
1546+ std::memcpy (newImageData.data () + offset, imageSpan .data (), length);
15281547 }
15291548 }
15301549 }
0 commit comments