Skip to content

Commit

Permalink
fixed an alignment issue in ktx loader
Browse files Browse the repository at this point in the history
  • Loading branch information
kopaka committed Jul 20, 2023
1 parent c5d7131 commit 0ca1570
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 4 deletions.
25 changes: 21 additions & 4 deletions DxImageLoader/ktx_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,27 @@ std::unique_ptr<image::IImage> ktx_load_base(ktxTexture* ktex, gli::format forma
ktxLvlSize *= res->getDepth(mip); // is not multiplied with depth layer
size_t size;
auto dstData = res->getData(dstLayer, mip, size);
if (ktxLvlSize != size)
throw std::runtime_error("suggested level size of gli does not match with ktx api");
memcpy(dstData, ktex->pData + offset, size);

if(ktxLvlSize == size)
{
memcpy(dstData, ktex->pData + offset, size); // alignment matches
}
else if(size < ktxLvlSize)
{
// calculate size with alignment after each row
size_t rows = res->getHeight(mip) * res->getDepth(mip);
size_t unalignedRow = size / rows;
size_t alignedRow = ktxLvlSize / rows;
auto srcData = ktex->pData;
//std::vector<uint8_t> debugSrc(srcData, srcData + ktxLvlSize);
// copy row by row
for(size_t r = 0; r < rows; ++r)
{
memcpy(dstData, srcData, unalignedRow);
dstData += unalignedRow;
srcData += alignedRow;
}
}
else throw std::runtime_error("suggested level size of gli does not match with ktx api");
}
++dstLayer;
}
Expand Down
53 changes: 53 additions & 0 deletions FrameworkTests/ImageLoader/KtxSamples.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using ImageFramework.DirectX;
using ImageFramework.ImageLoader;
using ImageFramework.Model;
using ImageFramework.Utility;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SharpDX.DXGI;

Expand All @@ -17,13 +20,31 @@ public class KtxSamples

public static string ImportBadDir = TestData.Directory + "ktx-software\\badktx2\\";

public static string ExportDir = TestData.Directory + "export/";

[ClassInitialize]
public static void Init(TestContext context)
{
TestData.CreateOutputDirectory(ExportDir);
}

private static string[] RemoveUnsupportedFile(string[] files)
{
// remove all files that have 'eac' or 'etc' in their name (these compressions are not supported yet)
return files.Where(f =>
!f.Contains("eac") && !f.Contains("EAC") &&
!f.Contains("etc") && !f.Contains("ETC")
).ToArray();
}

[TestMethod]
public void ImportTestImagesKtx()
{
// get all files in the directory
var files = System.IO.Directory.GetFiles(ImportDir, "*.ktx", System.IO.SearchOption.TopDirectoryOnly);
// filter files so they only end with .ktx (not ktx2)
files = files.Where(f => f.EndsWith(".ktx")).ToArray();
files = RemoveUnsupportedFile(files);
TryImportAllFiles(files);
}

Expand All @@ -32,9 +53,41 @@ public void ImportTestImagesKtx2()
{
// get all files in the directory
var files = System.IO.Directory.GetFiles(ImportDir, "*.ktx2", System.IO.SearchOption.TopDirectoryOnly);
files = RemoveUnsupportedFile(files);
TryImportAllFiles(files);
}

[TestMethod]
public void AlignmentKtx()
{
// this file uses the RGB format and the width of each row is not a multiple of 4 (this can be tricky to import/export)
var filename = ImportDir + "hi_mark_sq.ktx";
var model = new Models();
model.AddImageFromFile(filename);

// the following needs to be fulfilled:
Assert.AreEqual(145, model.Images.GetWidth(0));
Assert.AreEqual(model.Images.Images[0].OriginalFormat, GliFormat.RGB8_UNORM);

// export and reimport
var filename2 = ExportDir + "hi_mark_sq";
model.ExportPipelineImage(filename2, "ktx", GliFormat.RGB8_UNORM);

// reimport
model.AddImageFromFile(filename2 + ".ktx");

// compare colors
var srcImg = model.Images.Images[0].Image as TextureArray2D;
var expImg = model.Images.Images[1].Image as TextureArray2D;
Assert.IsNotNull(srcImg);
Assert.IsNotNull(expImg);

var srcColors = srcImg.GetPixelColors(LayerMipmapSlice.Mip0);
var expColors = expImg.GetPixelColors(LayerMipmapSlice.Mip0);

TestData.CompareColors(srcColors, expColors);
}

void TryImportAllFiles(string[] files)
{
string errors = "";
Expand Down
Binary file not shown.

0 comments on commit 0ca1570

Please sign in to comment.