Skip to content

Commit ec826b4

Browse files
DecodeJpeg: added option to only decode image description
1 parent 6076255 commit ec826b4

File tree

3 files changed

+76
-55
lines changed

3 files changed

+76
-55
lines changed

Tests/DiligentToolsTest/src/JPEGCodecTest.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,25 @@ TEST(Tools_TextureLoader, JPEGCodec)
5757
}
5858
}
5959

60-
auto pJpgData = DataBlobImpl::Create();
60+
RefCntAutoPtr<IDataBlob> pJpgData = DataBlobImpl::Create();
6161

62-
auto Res = EncodeJpeg(RefPixels.data(), TestImgWidth, TestImgHeight, 100, pJpgData);
62+
ENCODE_JPEG_RESULT Res = EncodeJpeg(RefPixels.data(), TestImgWidth, TestImgHeight, 100, pJpgData);
6363
ASSERT_EQ(Res, ENCODE_JPEG_RESULT_OK);
6464

65-
auto pDecodedPixelsBlob = DataBlobImpl::Create();
65+
{
66+
ImageDesc DecodedImgDesc;
67+
EXPECT_EQ(DecodeJpeg(pJpgData, nullptr, &DecodedImgDesc), DECODE_JPEG_RESULT_OK);
68+
69+
ASSERT_EQ(DecodedImgDesc.Width, TestImgWidth);
70+
ASSERT_EQ(DecodedImgDesc.Height, TestImgHeight);
71+
ASSERT_EQ(DecodedImgDesc.NumComponents, NumComponents);
72+
ASSERT_EQ(DecodedImgDesc.ComponentType, VT_UINT8);
73+
}
74+
75+
RefCntAutoPtr<IDataBlob> pDecodedPixelsBlob = DataBlobImpl::Create();
6676

6777
ImageDesc DecodedImgDesc;
68-
DecodeJpeg(pJpgData, pDecodedPixelsBlob, &DecodedImgDesc);
78+
EXPECT_EQ(DecodeJpeg(pJpgData, pDecodedPixelsBlob, &DecodedImgDesc), DECODE_JPEG_RESULT_OK);
6979

7080
ASSERT_EQ(DecodedImgDesc.Width, TestImgWidth);
7181
ASSERT_EQ(DecodedImgDesc.Height, TestImgHeight);
@@ -79,9 +89,9 @@ TEST(Tools_TextureLoader, JPEGCodec)
7989
{
8090
for (Uint32 c = 0; c < NumComponents; ++c)
8191
{
82-
auto RefVal = RefPixels[(x + y * TestImgWidth) * NumComponents + c];
83-
auto TestVal = pTestPixels[x * DecodedImgDesc.NumComponents + c + y * DecodedImgDesc.RowStride];
84-
auto Diff = std::abs(static_cast<int>(RefVal) - static_cast<int>(TestVal));
92+
Uint8 RefVal = RefPixels[(x + y * TestImgWidth) * NumComponents + c];
93+
Uint8 TestVal = pTestPixels[x * DecodedImgDesc.NumComponents + c + y * DecodedImgDesc.RowStride];
94+
int Diff = std::abs(static_cast<int>(RefVal) - static_cast<int>(TestVal));
8595
EXPECT_LE(Diff, 1) << "[" << x << "," << y << "][" << c << "]: " << static_cast<int>(RefVal) << " vs " << static_cast<int>(TestVal);
8696
}
8797
}

TextureLoader/interface/JPEGCodec.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ DILIGENT_TYPED_ENUM(ENCODE_JPEG_RESULT, Uint32)
6969
/// (for instance, components of 3-channel image will be written as |r|g|b|r|g|b|r|g|b|...).
7070
/// \param [out] pDstImgDesc - Decoded image description.
7171
/// \return Decoding result, see Diligent::DECODE_JPEG_RESULT.
72+
///
73+
/// \remarks If pDstPixels is null, the function will only decode the image description and return DECODE_JPEG_RESULT_OK.
7274
DECODE_JPEG_RESULT DILIGENT_GLOBAL_FUNCTION(DecodeJpeg)(const IDataBlob* pSrcJpegBits,
7375
IDataBlob* pDstPixels,
7476
ImageDesc* pDstImgDesc);

TextureLoader/src/JPEGCodec.c

Lines changed: 57 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ DECODE_JPEG_RESULT Diligent_DecodeJpeg(const IDataBlob* pSrcJpegBits,
6262
IDataBlob* pDstPixels,
6363
ImageDesc* pDstImgDesc)
6464
{
65-
if (!pSrcJpegBits || !pDstPixels || !pDstImgDesc)
65+
if (!pSrcJpegBits || !pDstImgDesc)
6666
return DECODE_JPEG_RESULT_INVALID_ARGUMENTS;
6767

6868
// https://github.com/LuaDist/libjpeg/blob/master/example.c
@@ -105,55 +105,64 @@ DECODE_JPEG_RESULT Diligent_DecodeJpeg(const IDataBlob* pSrcJpegBits,
105105
// (b) we passed TRUE to reject a tables-only JPEG file as an error.
106106
// See libjpeg.txt for more info.
107107

108-
109-
// Step 4: set parameters for decompression
110-
111-
// In this example, we don't need to change any of the defaults set by
112-
// jpeg_read_header(), so we do nothing here.
113-
114-
115-
// Step 5: Start decompressor
116-
117-
jpeg_start_decompress(&cinfo);
118-
// We can ignore the return value since suspension is not possible
119-
// with the stdio data source.
120-
121-
// We may need to do some setup of our own at this point before reading
122-
// the data. After jpeg_start_decompress() we have the correct scaled
123-
// output image dimensions available, as well as the output colormap
124-
// if we asked for color quantization.
125-
126-
pDstImgDesc->Width = cinfo.output_width;
127-
pDstImgDesc->Height = cinfo.output_height;
128-
pDstImgDesc->ComponentType = VT_UINT8;
129-
pDstImgDesc->NumComponents = cinfo.output_components;
130-
pDstImgDesc->RowStride = pDstImgDesc->Width * pDstImgDesc->NumComponents;
131-
pDstImgDesc->RowStride = (pDstImgDesc->RowStride + 3u) & ~3u;
132-
133-
IDataBlob_Resize(pDstPixels, (size_t)pDstImgDesc->RowStride * pDstImgDesc->Height);
134-
// Step 6: while (scan lines remain to be read)
135-
// jpeg_read_scanlines(...);
136-
137-
// Here we use the library's state variable cinfo.output_scanline as the
138-
// loop counter, so that we don't have to keep track ourselves.
139-
while (cinfo.output_scanline < cinfo.output_height)
108+
if (pDstPixels != NULL)
140109
{
141-
// jpeg_read_scanlines expects an array of pointers to scanlines.
142-
// Here the array is only one element long, but you could ask for
143-
// more than one scanline at a time if that's more convenient.
144-
145-
Uint8* pScanline0 = IDataBlob_GetDataPtr(pDstPixels, 0);
146-
Uint8* pDstScanline = pScanline0 + cinfo.output_scanline * (size_t)pDstImgDesc->RowStride;
147-
JSAMPROW RowPtrs[1];
148-
RowPtrs[0] = (JSAMPROW)pDstScanline;
149-
jpeg_read_scanlines(&cinfo, RowPtrs, 1);
110+
// Step 4: set parameters for decompression
111+
112+
// In this example, we don't need to change any of the defaults set by
113+
// jpeg_read_header(), so we do nothing here.
114+
115+
116+
// Step 5: Start decompressor
117+
118+
jpeg_start_decompress(&cinfo);
119+
// We can ignore the return value since suspension is not possible
120+
// with the stdio data source.
121+
122+
// We may need to do some setup of our own at this point before reading
123+
// the data. After jpeg_start_decompress() we have the correct scaled
124+
// output image dimensions available, as well as the output colormap
125+
// if we asked for color quantization.
126+
127+
pDstImgDesc->Width = cinfo.output_width;
128+
pDstImgDesc->Height = cinfo.output_height;
129+
pDstImgDesc->ComponentType = VT_UINT8;
130+
pDstImgDesc->NumComponents = cinfo.output_components;
131+
pDstImgDesc->RowStride = pDstImgDesc->Width * pDstImgDesc->NumComponents;
132+
pDstImgDesc->RowStride = (pDstImgDesc->RowStride + 3u) & ~3u;
133+
134+
IDataBlob_Resize(pDstPixels, (size_t)pDstImgDesc->RowStride * pDstImgDesc->Height);
135+
// Step 6: while (scan lines remain to be read)
136+
// jpeg_read_scanlines(...);
137+
138+
// Here we use the library's state variable cinfo.output_scanline as the
139+
// loop counter, so that we don't have to keep track ourselves.
140+
while (cinfo.output_scanline < cinfo.output_height)
141+
{
142+
// jpeg_read_scanlines expects an array of pointers to scanlines.
143+
// Here the array is only one element long, but you could ask for
144+
// more than one scanline at a time if that's more convenient.
145+
146+
Uint8* pScanline0 = IDataBlob_GetDataPtr(pDstPixels, 0);
147+
Uint8* pDstScanline = pScanline0 + cinfo.output_scanline * (size_t)pDstImgDesc->RowStride;
148+
JSAMPROW RowPtrs[1];
149+
RowPtrs[0] = (JSAMPROW)pDstScanline;
150+
jpeg_read_scanlines(&cinfo, RowPtrs, 1);
151+
}
152+
153+
// Step 7: Finish decompression
154+
155+
jpeg_finish_decompress(&cinfo);
156+
// We can ignore the return value since suspension is not possible
157+
// with the stdio data source.
158+
}
159+
else
160+
{
161+
pDstImgDesc->Width = cinfo.image_width;
162+
pDstImgDesc->Height = cinfo.image_height;
163+
pDstImgDesc->ComponentType = VT_UINT8;
164+
pDstImgDesc->NumComponents = cinfo.num_components;
150165
}
151-
152-
// Step 7: Finish decompression
153-
154-
jpeg_finish_decompress(&cinfo);
155-
// We can ignore the return value since suspension is not possible
156-
// with the stdio data source.
157166

158167
// Step 8: Release JPEG decompression object
159168

0 commit comments

Comments
 (0)