Skip to content

Commit 5015c9e

Browse files
Image: reworked TIFF loading
1 parent 08b31f1 commit 5015c9e

File tree

2 files changed

+82
-74
lines changed

2 files changed

+82
-74
lines changed

TextureLoader/interface/Image.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ struct Image : public ObjectBase<IObject>
183183
const ImageDesc& Desc,
184184
RefCntAutoPtr<IDataBlob> pPixels);
185185

186-
void LoadTiffFile(const IDataBlob* pFileData, const ImageLoadInfo& LoadInfo);
186+
static void LoadTiffFile(const void* pData, size_t Size, IDataBlob* pDstPixels, ImageDesc& Desc);
187187

188188
ImageDesc m_Desc;
189189
RefCntAutoPtr<IDataBlob> m_pData;

TextureLoader/src/Image.cpp

Lines changed: 81 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -68,38 +68,40 @@ namespace Diligent
6868
class TIFFClientOpenWrapper
6969
{
7070
public:
71-
explicit TIFFClientOpenWrapper(const IDataBlob* pData) noexcept :
71+
TIFFClientOpenWrapper(const void* pData, size_t Size) noexcept :
7272
m_Offset{0},
73-
m_Size{pData->GetSize()},
73+
m_Size{Size},
7474
m_pData{pData}
7575
{
7676
}
7777

78+
explicit TIFFClientOpenWrapper(IDataBlob* pDstBlob) noexcept :
79+
m_pDstBlob{pDstBlob}
80+
{}
81+
7882
static tmsize_t TIFFReadProc(thandle_t pClientData, void* pBuffer, tmsize_t Size)
7983
{
80-
TIFFClientOpenWrapper* pThis = static_cast<TIFFClientOpenWrapper*>(pClientData);
81-
const void* pSrcPtr = pThis->m_pData->GetConstDataPtr(pThis->m_Offset);
84+
TIFFClientOpenWrapper* pThis = static_cast<TIFFClientOpenWrapper*>(pClientData);
85+
VERIFY(pThis->m_pData != nullptr, "TIFF file was not opened for reading");
86+
const void* pSrcPtr = static_cast<const Uint8*>(pThis->m_pData) + pThis->m_Offset;
8287
memcpy(pBuffer, pSrcPtr, Size);
8388
pThis->m_Offset += Size;
8489
return Size;
8590
}
8691

8792
static tmsize_t TIFFWriteProc(thandle_t pClientData, void* pBuffer, tmsize_t Size)
8893
{
89-
#if 0
9094
TIFFClientOpenWrapper* pThis = static_cast<TIFFClientOpenWrapper*>(pClientData);
95+
VERIFY(pThis->m_pDstBlob != nullptr, "TIFF file was not opened for writing");
9196
if (pThis->m_Offset + Size > pThis->m_Size)
9297
{
9398
pThis->m_Size = pThis->m_Offset + Size;
94-
pThis->m_pData->Resize(pThis->m_Size);
99+
pThis->m_pDstBlob->Resize(pThis->m_Size);
95100
}
96-
auto* pDstPtr = pThis->m_pData->GetDataPtr(pThis->m_Offset);
101+
void* pDstPtr = pThis->m_pDstBlob->GetDataPtr(pThis->m_Offset);
97102
memcpy(pDstPtr, pBuffer, Size);
98103
pThis->m_Offset += Size;
99104
return Size;
100-
#endif
101-
UNSUPPORTED("TIFF write is not supported");
102-
return 0;
103105
}
104106

105107
static toff_t TIFFSeekProc(thandle_t pClientData, toff_t Offset, int Whence)
@@ -118,10 +120,11 @@ class TIFFClientOpenWrapper
118120

119121
static int TIFFCloseProc(thandle_t pClientData)
120122
{
121-
auto* pThis = reinterpret_cast<TIFFClientOpenWrapper*>(pClientData);
122-
pThis->m_pData = nullptr;
123-
pThis->m_Size = 0;
124-
pThis->m_Offset = 0;
123+
auto* pThis = reinterpret_cast<TIFFClientOpenWrapper*>(pClientData);
124+
pThis->m_pData = nullptr;
125+
pThis->m_pDstBlob = nullptr;
126+
pThis->m_Size = 0;
127+
pThis->m_Offset = 0;
125128
return 0;
126129
}
127130

@@ -143,14 +146,15 @@ class TIFFClientOpenWrapper
143146
}
144147

145148
private:
146-
size_t m_Offset = 0;
147-
size_t m_Size = 0;
148-
const IDataBlob* m_pData = nullptr;
149+
size_t m_Offset = 0;
150+
size_t m_Size = 0;
151+
const void* m_pData = nullptr;
152+
IDataBlob* m_pDstBlob = nullptr;
149153
};
150154

151-
void Image::LoadTiffFile(const IDataBlob* pFileData, const ImageLoadInfo& LoadInfo)
155+
void Image::LoadTiffFile(const void* pData, size_t Size, IDataBlob* pDstPixels, ImageDesc& Desc)
152156
{
153-
TIFFClientOpenWrapper TiffClientOpenWrpr(pFileData);
157+
TIFFClientOpenWrapper TiffClientOpenWrpr{pData, Size};
154158

155159
auto TiffFile = TIFFClientOpen("", "rm", &TiffClientOpenWrpr,
156160
TIFFClientOpenWrapper::TIFFReadProc,
@@ -161,15 +165,15 @@ void Image::LoadTiffFile(const IDataBlob* pFileData, const ImageLoadInfo& LoadIn
161165
TIFFClientOpenWrapper::TIFFMapFileProc,
162166
TIFFClientOpenWrapper::TIFFUnmapFileProc);
163167

164-
TIFFGetField(TiffFile, TIFFTAG_IMAGEWIDTH, &m_Desc.Width);
165-
TIFFGetField(TiffFile, TIFFTAG_IMAGELENGTH, &m_Desc.Height);
168+
TIFFGetField(TiffFile, TIFFTAG_IMAGEWIDTH, &Desc.Width);
169+
TIFFGetField(TiffFile, TIFFTAG_IMAGELENGTH, &Desc.Height);
166170

167171
Uint16 SamplesPerPixel = 0;
168172
// SamplesPerPixel is usually 1 for bilevel, grayscale, and palette-color images.
169173
// SamplesPerPixel is usually 3 for RGB images. If this value is higher, ExtraSamples
170174
// should give an indication of the meaning of the additional channels.
171175
TIFFGetField(TiffFile, TIFFTAG_SAMPLESPERPIXEL, &SamplesPerPixel);
172-
m_Desc.NumComponents = SamplesPerPixel;
176+
Desc.NumComponents = SamplesPerPixel;
173177

174178
Uint16 BitsPerSample = 0;
175179
TIFFGetField(TiffFile, TIFFTAG_BITSPERSAMPLE, &BitsPerSample);
@@ -184,28 +188,28 @@ void Image::LoadTiffFile(const IDataBlob* pFileData, const ImageLoadInfo& LoadIn
184188
case SAMPLEFORMAT_UINT:
185189
switch (BitsPerSample)
186190
{
187-
case 8: m_Desc.ComponentType = VT_UINT8; break;
188-
case 16: m_Desc.ComponentType = VT_UINT16; break;
189-
case 32: m_Desc.ComponentType = VT_UINT32; break;
191+
case 8: Desc.ComponentType = VT_UINT8; break;
192+
case 16: Desc.ComponentType = VT_UINT16; break;
193+
case 32: Desc.ComponentType = VT_UINT32; break;
190194
default: LOG_ERROR_AND_THROW(BitsPerSample, " is not a valid UINT component bit depth. Only 8, 16 and 32 are allowed");
191195
}
192196
break;
193197

194198
case SAMPLEFORMAT_INT:
195199
switch (BitsPerSample)
196200
{
197-
case 8: m_Desc.ComponentType = VT_INT8; break;
198-
case 16: m_Desc.ComponentType = VT_INT16; break;
199-
case 32: m_Desc.ComponentType = VT_INT32; break;
201+
case 8: Desc.ComponentType = VT_INT8; break;
202+
case 16: Desc.ComponentType = VT_INT16; break;
203+
case 32: Desc.ComponentType = VT_INT32; break;
200204
default: LOG_ERROR_AND_THROW(BitsPerSample, " is not a valid INT component bit depth. Only 8, 16 and 32 are allowed");
201205
}
202206
break;
203207

204208
case SAMPLEFORMAT_IEEEFP:
205209
switch (BitsPerSample)
206210
{
207-
case 16: m_Desc.ComponentType = VT_FLOAT16; break;
208-
case 32: m_Desc.ComponentType = VT_FLOAT32; break;
211+
case 16: Desc.ComponentType = VT_FLOAT16; break;
212+
case 32: Desc.ComponentType = VT_FLOAT32; break;
209213
default: LOG_ERROR_AND_THROW(BitsPerSample, " is not a valid FLOAT component bit depth. Only 16 and 32 are allowed");
210214
}
211215
break;
@@ -226,63 +230,67 @@ void Image::LoadTiffFile(const IDataBlob* pFileData, const ImageLoadInfo& LoadIn
226230
LOG_ERROR_AND_THROW("Unknown sample format: ", Uint32{SampleFormat});
227231
}
228232

229-
size_t ScanlineSize = TIFFScanlineSize(TiffFile);
230-
m_Desc.RowStride = AlignUp(m_Desc.Width * m_Desc.NumComponents * (BitsPerSample / 8), 4u);
231-
m_pData->Resize(size_t{m_Desc.Height} * size_t{m_Desc.RowStride});
232-
233-
Uint16 PlanarConfig = 0;
234-
TIFFGetField(TiffFile, TIFFTAG_PLANARCONFIG, &PlanarConfig);
235-
if (PlanarConfig == PLANARCONFIG_CONTIG || m_Desc.NumComponents == 1)
233+
if (pDstPixels != nullptr)
236234
{
237-
VERIFY_EXPR(m_Desc.RowStride >= ScanlineSize);
238-
Uint8* pDataPtr = m_pData->GetDataPtr<Uint8>();
239-
for (Uint32 row = 0; row < m_Desc.Height; row++, pDataPtr += m_Desc.RowStride)
235+
size_t ScanlineSize = TIFFScanlineSize(TiffFile);
236+
Desc.RowStride = AlignUp(Desc.Width * Desc.NumComponents * (BitsPerSample / 8), 4u);
237+
pDstPixels->Resize(size_t{Desc.Height} * size_t{Desc.RowStride});
238+
239+
Uint16 PlanarConfig = 0;
240+
TIFFGetField(TiffFile, TIFFTAG_PLANARCONFIG, &PlanarConfig);
241+
if (PlanarConfig == PLANARCONFIG_CONTIG || Desc.NumComponents == 1)
240242
{
241-
TIFFReadScanline(TiffFile, pDataPtr, row);
243+
VERIFY_EXPR(Desc.RowStride >= ScanlineSize);
244+
Uint8* pDataPtr = pDstPixels->GetDataPtr<Uint8>();
245+
for (Uint32 row = 0; row < Desc.Height; row++, pDataPtr += Desc.RowStride)
246+
{
247+
TIFFReadScanline(TiffFile, pDataPtr, row);
248+
}
242249
}
243-
}
244-
else if (PlanarConfig == PLANARCONFIG_SEPARATE)
245-
{
246-
std::vector<Uint8> ScanlineData(ScanlineSize);
247-
for (Uint32 row = 0; row < m_Desc.Height; ++row)
250+
else if (PlanarConfig == PLANARCONFIG_SEPARATE)
248251
{
249-
for (Uint16 comp = 0; comp < m_Desc.NumComponents; ++comp)
252+
std::vector<Uint8> ScanlineData(ScanlineSize);
253+
for (Uint32 row = 0; row < Desc.Height; ++row)
250254
{
251-
Uint8* const pDstRow = m_pData->GetDataPtr<Uint8>() + m_Desc.RowStride * row + comp;
255+
for (Uint16 comp = 0; comp < Desc.NumComponents; ++comp)
256+
{
257+
Uint8* const pDstRow = pDstPixels->GetDataPtr<Uint8>() + Desc.RowStride * row + comp;
252258

253-
TIFFReadScanline(TiffFile, ScanlineData.data(), row, comp);
259+
TIFFReadScanline(TiffFile, ScanlineData.data(), row, comp);
254260

255-
auto CopyComponet = [Width = m_Desc.Width, NumComp = m_Desc.NumComponents](const auto* pSrc, auto* pDst) {
256-
for (Uint32 x = 0; x < Width; ++x)
257-
{
258-
pDst[x * NumComp] = pSrc[x];
259-
}
260-
};
261+
auto CopyComponet = [Width = Desc.Width, NumComp = Desc.NumComponents](const auto* pSrc, auto* pDst) {
262+
for (Uint32 x = 0; x < Width; ++x)
263+
{
264+
pDst[x * NumComp] = pSrc[x];
265+
}
266+
};
261267

262-
switch (BitsPerSample)
263-
{
264-
case 8:
265-
CopyComponet(reinterpret_cast<const Uint8*>(ScanlineData.data()), reinterpret_cast<Uint8*>(pDstRow));
266-
break;
268+
switch (BitsPerSample)
269+
{
270+
case 8:
271+
CopyComponet(reinterpret_cast<const Uint8*>(ScanlineData.data()), reinterpret_cast<Uint8*>(pDstRow));
272+
break;
267273

268-
case 16:
269-
CopyComponet(reinterpret_cast<const Uint16*>(ScanlineData.data()), reinterpret_cast<Uint16*>(pDstRow));
270-
break;
274+
case 16:
275+
CopyComponet(reinterpret_cast<const Uint16*>(ScanlineData.data()), reinterpret_cast<Uint16*>(pDstRow));
276+
break;
271277

272-
case 32:
273-
CopyComponet(reinterpret_cast<const Uint32*>(ScanlineData.data()), reinterpret_cast<Uint32*>(pDstRow));
274-
break;
278+
case 32:
279+
CopyComponet(reinterpret_cast<const Uint32*>(ScanlineData.data()), reinterpret_cast<Uint32*>(pDstRow));
280+
break;
275281

276-
default:
277-
UNEXPECTED("Unexpected component bit depth (", BitsPerSample, ").");
282+
default:
283+
UNEXPECTED("Unexpected component bit depth (", BitsPerSample, ").");
284+
}
278285
}
279286
}
280287
}
288+
else
289+
{
290+
UNEXPECTED("Unexpected planar configuration (", PlanarConfig, ").");
291+
}
281292
}
282-
else
283-
{
284-
UNEXPECTED("Unexpected planar configuration (", PlanarConfig, ").");
285-
}
293+
286294
TIFFClose(TiffFile);
287295
}
288296

@@ -356,7 +364,7 @@ Image::Image(IReferenceCounters* pRefCounters,
356364
{
357365
if (LoadInfo.Format == IMAGE_FILE_FORMAT_TIFF)
358366
{
359-
LoadTiffFile(pFileData, LoadInfo);
367+
LoadTiffFile(pFileData->GetConstDataPtr(), pFileData->GetSize(), m_pData, m_Desc);
360368
}
361369
else if (LoadInfo.Format == IMAGE_FILE_FORMAT_HDR)
362370
{

0 commit comments

Comments
 (0)