diff --git a/TextureLoader/src/Image.cpp b/TextureLoader/src/Image.cpp index d8db3dd0..63c67d7d 100644 --- a/TextureLoader/src/Image.cpp +++ b/TextureLoader/src/Image.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 Diligent Graphics LLC + * Copyright 2019-2024 Diligent Graphics LLC * Copyright 2015-2019 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -209,12 +209,60 @@ void Image::LoadTiffFile(IDataBlob* pFileData, const ImageLoadInfo& LoadInfo) } auto ScanlineSize = TIFFScanlineSize(TiffFile); - m_Desc.RowStride = AlignUp(static_cast(ScanlineSize), 4u); + m_Desc.RowStride = AlignUp(m_Desc.Width * m_Desc.NumComponents * (BitsPerSample / 8), 4u); m_pData->Resize(size_t{m_Desc.Height} * size_t{m_Desc.RowStride}); - auto* pDataPtr = reinterpret_cast(m_pData->GetDataPtr()); - for (Uint32 row = 0; row < m_Desc.Height; row++, pDataPtr += m_Desc.RowStride) + + Uint16 PlanarConfig = 0; + TIFFGetField(TiffFile, TIFFTAG_PLANARCONFIG, &PlanarConfig); + if (PlanarConfig == PLANARCONFIG_CONTIG || m_Desc.NumComponents == 1) + { + VERIFY_EXPR(m_Desc.RowStride >= static_cast(ScanlineSize)); + auto* pDataPtr = reinterpret_cast(m_pData->GetDataPtr()); + for (Uint32 row = 0; row < m_Desc.Height; row++, pDataPtr += m_Desc.RowStride) + { + TIFFReadScanline(TiffFile, pDataPtr, row); + } + } + else if (PlanarConfig == PLANARCONFIG_SEPARATE) + { + std::vector ScanlineData(ScanlineSize); + for (Uint16 comp = 0; comp < m_Desc.NumComponents; ++comp) + { + for (Uint32 row = 0; row < m_Desc.Height; ++row) + { + TIFFReadScanline(TiffFile, ScanlineData.data(), row, comp); + + auto CopyComponet = [&](const auto* pSrc, auto* pDst) { + pDst += row * m_Desc.Width * m_Desc.NumComponents + comp; + for (Uint32 x = 0; x < m_Desc.Width; ++x) + { + pDst[x * m_Desc.NumComponents] = pSrc[x]; + } + }; + + switch (BitsPerSample) + { + case 8: + CopyComponet(reinterpret_cast(ScanlineData.data()), reinterpret_cast(m_pData->GetDataPtr())); + break; + + case 16: + CopyComponet(reinterpret_cast(ScanlineData.data()), reinterpret_cast(m_pData->GetDataPtr())); + break; + + case 32: + CopyComponet(reinterpret_cast(ScanlineData.data()), reinterpret_cast(m_pData->GetDataPtr())); + break; + + default: + UNEXPECTED("Unexpected component bit depth (", BitsPerSample, ")."); + } + } + } + } + else { - TIFFReadScanline(TiffFile, pDataPtr, row); + UNEXPECTED("Unexpected planar configuration (", PlanarConfig, ")."); } TIFFClose(TiffFile); }