summaryrefslogtreecommitdiffstats
path: root/TextureLoader/src/Image.cpp
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2019-04-20 03:26:31 +0000
committerEgor Yusov <egor.yusov@gmail.com>2019-04-20 03:26:31 +0000
commit30079f036c5f3a79873b4929755dfaf64f9a317b (patch)
tree43d38ef8a8827296510c9f4e3e99901f132eb8ba /TextureLoader/src/Image.cpp
parentUpdates to match API 240022 (diff)
downloadDiligentTools-30079f036c5f3a79873b4929755dfaf64f9a317b.tar.gz
DiligentTools-30079f036c5f3a79873b4929755dfaf64f9a317b.zip
Using srgb conversions from graphics acessories
Diffstat (limited to 'TextureLoader/src/Image.cpp')
-rw-r--r--TextureLoader/src/Image.cpp976
1 files changed, 489 insertions, 487 deletions
diff --git a/TextureLoader/src/Image.cpp b/TextureLoader/src/Image.cpp
index e10e896..2fcbf63 100644
--- a/TextureLoader/src/Image.cpp
+++ b/TextureLoader/src/Image.cpp
@@ -41,607 +41,609 @@
namespace Diligent
{
- class TIFFClientOpenWrapper
- {
- public:
- TIFFClientOpenWrapper( IDataBlob *pData ) :
- m_Offset( 0 ),
- m_Size( pData->GetSize() ),
- m_pData( pData )
- {
- }
- static tmsize_t TIFFReadProc( thandle_t pClientData, void* pBuffer, tmsize_t Size )
- {
- auto *pThis = reinterpret_cast<TIFFClientOpenWrapper*>(pClientData);
- auto *pSrcPtr = reinterpret_cast<Uint8*>(pThis->m_pData->GetDataPtr()) + pThis->m_Offset;
- memcpy( pBuffer, pSrcPtr, Size );
- pThis->m_Offset += Size;
- return Size;
- }
+class TIFFClientOpenWrapper
+{
+public:
+ TIFFClientOpenWrapper( IDataBlob *pData ) :
+ m_Offset( 0 ),
+ m_Size( pData->GetSize() ),
+ m_pData( pData )
+ {
+ }
- static tmsize_t TIFFWriteProc( thandle_t pClientData, void* pBuffer, tmsize_t Size )
- {
- auto *pThis = reinterpret_cast<TIFFClientOpenWrapper*>(pClientData);
- if( pThis->m_Offset + Size > pThis->m_Size )
- {
- pThis->m_Size = pThis->m_Offset + Size;
- pThis->m_pData->Resize( pThis->m_Size );
- }
- auto *pDstPtr = reinterpret_cast<Uint8*>(pThis->m_pData->GetDataPtr()) + pThis->m_Offset;
- memcpy( pDstPtr, pBuffer, Size );
- pThis->m_Offset += Size;
- return Size;
- }
+ static tmsize_t TIFFReadProc( thandle_t pClientData, void* pBuffer, tmsize_t Size )
+ {
+ auto *pThis = reinterpret_cast<TIFFClientOpenWrapper*>(pClientData);
+ auto *pSrcPtr = reinterpret_cast<Uint8*>(pThis->m_pData->GetDataPtr()) + pThis->m_Offset;
+ memcpy( pBuffer, pSrcPtr, Size );
+ pThis->m_Offset += Size;
+ return Size;
+ }
- static toff_t TIFFSeekProc( thandle_t pClientData, toff_t Offset, int Whence )
+ static tmsize_t TIFFWriteProc( thandle_t pClientData, void* pBuffer, tmsize_t Size )
+ {
+ auto *pThis = reinterpret_cast<TIFFClientOpenWrapper*>(pClientData);
+ if( pThis->m_Offset + Size > pThis->m_Size )
{
- auto *pThis = reinterpret_cast<TIFFClientOpenWrapper*>(pClientData);
- switch( Whence )
- {
- case SEEK_SET: pThis->m_Offset = static_cast<size_t>(Offset); break;
- case SEEK_CUR: pThis->m_Offset += static_cast<size_t>(Offset); break;
- case SEEK_END: pThis->m_Offset = pThis->m_Size + static_cast<size_t>(Offset); break;
- default: UNEXPECTED( "Unexpected whence" );
- }
-
- return pThis->m_Offset;
+ pThis->m_Size = pThis->m_Offset + Size;
+ pThis->m_pData->Resize( pThis->m_Size );
}
+ auto *pDstPtr = reinterpret_cast<Uint8*>(pThis->m_pData->GetDataPtr()) + pThis->m_Offset;
+ memcpy( pDstPtr, pBuffer, Size );
+ pThis->m_Offset += Size;
+ return Size;
+ }
- static int TIFFCloseProc( thandle_t pClientData )
+ static toff_t TIFFSeekProc( thandle_t pClientData, toff_t Offset, int Whence )
+ {
+ auto *pThis = reinterpret_cast<TIFFClientOpenWrapper*>(pClientData);
+ switch( Whence )
{
- auto *pThis = reinterpret_cast<TIFFClientOpenWrapper*>(pClientData);
- pThis->m_pData.Release();
- pThis->m_Size = 0;
- pThis->m_Offset = 0;
- return 0;
+ case SEEK_SET: pThis->m_Offset = static_cast<size_t>(Offset); break;
+ case SEEK_CUR: pThis->m_Offset += static_cast<size_t>(Offset); break;
+ case SEEK_END: pThis->m_Offset = pThis->m_Size + static_cast<size_t>(Offset); break;
+ default: UNEXPECTED( "Unexpected whence" );
}
- static toff_t TIFFSizeProc( thandle_t pClientData )
- {
- auto *pThis = reinterpret_cast<TIFFClientOpenWrapper*>(pClientData);
- return pThis->m_Size;
- }
+ return pThis->m_Offset;
+ }
- static int TIFFMapFileProc( thandle_t pClientData, void** base, toff_t* size )
- {
- UNEXPECTED( "Client file mapping is not implemented. Use \'m\' when opening TIFF file to disable file mapping." );
- return 0;
- }
+ static int TIFFCloseProc( thandle_t pClientData )
+ {
+ auto *pThis = reinterpret_cast<TIFFClientOpenWrapper*>(pClientData);
+ pThis->m_pData.Release();
+ pThis->m_Size = 0;
+ pThis->m_Offset = 0;
+ return 0;
+ }
- static void TIFFUnmapFileProc( thandle_t pClientData, void* base, toff_t size )
- {
- UNEXPECTED( "Client file mapping is not implemented. Use \'m\' when opening TIFF file to disable file mapping." );
- }
+ static toff_t TIFFSizeProc( thandle_t pClientData )
+ {
+ auto *pThis = reinterpret_cast<TIFFClientOpenWrapper*>(pClientData);
+ return pThis->m_Size;
+ }
- private:
- size_t m_Offset;
- size_t m_Size;
- RefCntAutoPtr<IDataBlob> m_pData;
- };
+ static int TIFFMapFileProc( thandle_t pClientData, void** base, toff_t* size )
+ {
+ UNEXPECTED( "Client file mapping is not implemented. Use \'m\' when opening TIFF file to disable file mapping." );
+ return 0;
+ }
- void Image::LoadTiffFile( IDataBlob *pFileData, const ImageLoadInfo& LoadInfo )
+ static void TIFFUnmapFileProc( thandle_t pClientData, void* base, toff_t size )
{
- TIFFClientOpenWrapper TiffClientOpenWrpr(pFileData);
-
- auto TiffFile = TIFFClientOpen("", "rm", &TiffClientOpenWrpr,
- TIFFClientOpenWrapper::TIFFReadProc,
- TIFFClientOpenWrapper::TIFFWriteProc,
- TIFFClientOpenWrapper::TIFFSeekProc,
- TIFFClientOpenWrapper::TIFFCloseProc,
- TIFFClientOpenWrapper::TIFFSizeProc,
- TIFFClientOpenWrapper::TIFFMapFileProc,
- TIFFClientOpenWrapper::TIFFUnmapFileProc);
-
- TIFFGetField(TiffFile, TIFFTAG_IMAGEWIDTH, &m_Desc.Width);
- TIFFGetField(TiffFile, TIFFTAG_IMAGELENGTH, &m_Desc.Height);
+ UNEXPECTED( "Client file mapping is not implemented. Use \'m\' when opening TIFF file to disable file mapping." );
+ }
+
+private:
+ size_t m_Offset;
+ size_t m_Size;
+ RefCntAutoPtr<IDataBlob> m_pData;
+};
+
+void Image::LoadTiffFile( IDataBlob *pFileData, const ImageLoadInfo& LoadInfo )
+{
+ TIFFClientOpenWrapper TiffClientOpenWrpr(pFileData);
+
+ auto TiffFile = TIFFClientOpen("", "rm", &TiffClientOpenWrpr,
+ TIFFClientOpenWrapper::TIFFReadProc,
+ TIFFClientOpenWrapper::TIFFWriteProc,
+ TIFFClientOpenWrapper::TIFFSeekProc,
+ TIFFClientOpenWrapper::TIFFCloseProc,
+ TIFFClientOpenWrapper::TIFFSizeProc,
+ TIFFClientOpenWrapper::TIFFMapFileProc,
+ TIFFClientOpenWrapper::TIFFUnmapFileProc);
+
+ TIFFGetField(TiffFile, TIFFTAG_IMAGEWIDTH, &m_Desc.Width);
+ TIFFGetField(TiffFile, TIFFTAG_IMAGELENGTH, &m_Desc.Height);
- Uint16 SamplesPerPixel = 0;
- // SamplesPerPixel is usually 1 for bilevel, grayscale, and palette-color images.
- // SamplesPerPixel is usually 3 for RGB images. If this value is higher, ExtraSamples
- // should give an indication of the meaning of the additional channels.
- TIFFGetField(TiffFile, TIFFTAG_SAMPLESPERPIXEL, &SamplesPerPixel);
- m_Desc.NumComponents = SamplesPerPixel;
+ Uint16 SamplesPerPixel = 0;
+ // SamplesPerPixel is usually 1 for bilevel, grayscale, and palette-color images.
+ // SamplesPerPixel is usually 3 for RGB images. If this value is higher, ExtraSamples
+ // should give an indication of the meaning of the additional channels.
+ TIFFGetField(TiffFile, TIFFTAG_SAMPLESPERPIXEL, &SamplesPerPixel);
+ m_Desc.NumComponents = SamplesPerPixel;
- Uint16 BitsPerSample = 0;
- TIFFGetField(TiffFile, TIFFTAG_BITSPERSAMPLE, &BitsPerSample);
- m_Desc.BitsPerPixel = m_Desc.NumComponents * BitsPerSample;
-
- auto ScanlineSize = TIFFScanlineSize(TiffFile);
- m_Desc.RowStride = Align(static_cast<Uint32>( ScanlineSize ), 4u);
- m_pData->Resize(size_t{m_Desc.Height} * size_t{m_Desc.RowStride});
- auto *pDataPtr = reinterpret_cast<Uint8*>( m_pData->GetDataPtr() );
- for (Uint32 row = 0; row < m_Desc.Height; row++, pDataPtr += m_Desc.RowStride)
- {
- TIFFReadScanline(TiffFile, pDataPtr, row);
- }
- TIFFClose(TiffFile);
+ Uint16 BitsPerSample = 0;
+ TIFFGetField(TiffFile, TIFFTAG_BITSPERSAMPLE, &BitsPerSample);
+ m_Desc.BitsPerPixel = m_Desc.NumComponents * BitsPerSample;
+
+ auto ScanlineSize = TIFFScanlineSize(TiffFile);
+ m_Desc.RowStride = Align(static_cast<Uint32>( ScanlineSize ), 4u);
+ m_pData->Resize(size_t{m_Desc.Height} * size_t{m_Desc.RowStride});
+ auto *pDataPtr = reinterpret_cast<Uint8*>( m_pData->GetDataPtr() );
+ for (Uint32 row = 0; row < m_Desc.Height; row++, pDataPtr += m_Desc.RowStride)
+ {
+ TIFFReadScanline(TiffFile, pDataPtr, row);
}
+ TIFFClose(TiffFile);
+}
- class PNGReadFnHelper
+class PNGReadFnHelper
+{
+public:
+ PNGReadFnHelper( IDataBlob *pData ) :
+ m_pData( pData ),
+ m_Offset( 0 )
{
- public:
- PNGReadFnHelper( IDataBlob *pData ) :
- m_pData( pData ),
- m_Offset( 0 )
- {
- }
+ }
- static void ReadData( png_structp pngPtr, png_bytep data, png_size_t length )
- {
- auto pThis = reinterpret_cast<PNGReadFnHelper*>( png_get_io_ptr(pngPtr) );
- memcpy( data, reinterpret_cast<Uint8*>(pThis->m_pData->GetDataPtr()) + pThis->m_Offset, length );
- pThis->m_Offset += length;
- }
+ static void ReadData( png_structp pngPtr, png_bytep data, png_size_t length )
+ {
+ auto pThis = reinterpret_cast<PNGReadFnHelper*>( png_get_io_ptr(pngPtr) );
+ memcpy( data, reinterpret_cast<Uint8*>(pThis->m_pData->GetDataPtr()) + pThis->m_Offset, length );
+ pThis->m_Offset += length;
+ }
- private:
- RefCntAutoPtr<IDataBlob> m_pData;
- size_t m_Offset;
- };
+private:
+ RefCntAutoPtr<IDataBlob> m_pData;
+ size_t m_Offset;
+};
- void Image::LoadPngFile( IDataBlob *pFileData, const ImageLoadInfo& LoadInfo )
- {
- // http://www.piko3d.net/tutorials/libpng-tutorial-loading-png-files-from-streams/
- // http://www.libpng.org/pub/png/book/chapter13.html#png.ch13.div.10
- // https://gist.github.com/niw/5963798
+void Image::LoadPngFile( IDataBlob *pFileData, const ImageLoadInfo& LoadInfo )
+{
+ // http://www.piko3d.net/tutorials/libpng-tutorial-loading-png-files-from-streams/
+ // http://www.libpng.org/pub/png/book/chapter13.html#png.ch13.div.10
+ // https://gist.github.com/niw/5963798
- PNGReadFnHelper ReadFnHelper(pFileData);
+ PNGReadFnHelper ReadFnHelper(pFileData);
- const size_t PngSigSize = 8;
- png_const_bytep pngsig = reinterpret_cast<png_const_bytep>(pFileData->GetDataPtr());
- //Let LibPNG check the signature. If this function returns 0, everything is OK.
- if( png_sig_cmp( pngsig, 0, PngSigSize ) != 0 )
- {
- LOG_ERROR_AND_THROW( "Invalid png signature" );
- }
+ const size_t PngSigSize = 8;
+ png_const_bytep pngsig = reinterpret_cast<png_const_bytep>(pFileData->GetDataPtr());
+ //Let LibPNG check the signature. If this function returns 0, everything is OK.
+ if( png_sig_cmp( pngsig, 0, PngSigSize ) != 0 )
+ {
+ LOG_ERROR_AND_THROW( "Invalid png signature" );
+ }
- png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- VERIFY(png, "png_create_read_struct() failed");
+ png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ VERIFY(png, "png_create_read_struct() failed");
- png_infop info = png_create_info_struct(png);
- VERIFY(info, "png_create_info_struct() failed");
+ png_infop info = png_create_info_struct(png);
+ VERIFY(info, "png_create_info_struct() failed");
- if( setjmp( png_jmpbuf( png ) ) )
- {
- // When an error occurs during parsing, libPNG will jump to here
- png_destroy_read_struct(&png, &info, (png_infopp)0);
- LOG_ERROR_AND_THROW( "Failed to read png file" );
- }
+ if( setjmp( png_jmpbuf( png ) ) )
+ {
+ // When an error occurs during parsing, libPNG will jump to here
+ png_destroy_read_struct(&png, &info, (png_infopp)0);
+ LOG_ERROR_AND_THROW( "Failed to read png file" );
+ }
- png_set_read_fn(png, (png_voidp)&ReadFnHelper, PNGReadFnHelper::ReadData);
+ png_set_read_fn(png, (png_voidp)&ReadFnHelper, PNGReadFnHelper::ReadData);
- png_read_info(png, info);
+ png_read_info(png, info);
- m_Desc.Width = png_get_image_width(png, info);
- m_Desc.Height = png_get_image_height(png, info);
- m_Desc.NumComponents = png_get_channels(png, info);
- auto bit_depth = png_get_bit_depth(png, info);
- m_Desc.BitsPerPixel = bit_depth * m_Desc.NumComponents;
+ m_Desc.Width = png_get_image_width(png, info);
+ m_Desc.Height = png_get_image_height(png, info);
+ m_Desc.NumComponents = png_get_channels(png, info);
+ auto bit_depth = png_get_bit_depth(png, info);
+ m_Desc.BitsPerPixel = bit_depth * m_Desc.NumComponents;
- // PNG files store 16-bit pixels in network byte order (big-endian, ie
- // most significant bytes first). png_set_swap() shall switch the byte-order
- // to little-endian (ie, least significant bits first).
- if( bit_depth == 16 )
- png_set_swap(png);
+ // PNG files store 16-bit pixels in network byte order (big-endian, ie
+ // most significant bytes first). png_set_swap() shall switch the byte-order
+ // to little-endian (ie, least significant bits first).
+ if( bit_depth == 16 )
+ png_set_swap(png);
#if 0
- auto color_type = png_get_color_type(png, info);
- // Read any color_type into 8bit depth, RGBA format.
- // See http://www.libpng.org/pub/png/libpng-manual.txt
+ auto color_type = png_get_color_type(png, info);
+ // Read any color_type into 8bit depth, RGBA format.
+ // See http://www.libpng.org/pub/png/libpng-manual.txt
- if( bit_depth == 16 )
- png_set_strip_16( png );
+ if( bit_depth == 16 )
+ png_set_strip_16( png );
- if( color_type == PNG_COLOR_TYPE_PALETTE )
- png_set_palette_to_rgb( png );
+ if( color_type == PNG_COLOR_TYPE_PALETTE )
+ png_set_palette_to_rgb( png );
- // PNG_COLOR_TYPE_GRAY_ALPHA is always 8 or 16bit depth.
- if( color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8 )
- png_set_expand_gray_1_2_4_to_8( png );
+ // PNG_COLOR_TYPE_GRAY_ALPHA is always 8 or 16bit depth.
+ if( color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8 )
+ png_set_expand_gray_1_2_4_to_8( png );
- if( png_get_valid( png, info, PNG_INFO_tRNS ) )
- png_set_tRNS_to_alpha( png );
+ if( png_get_valid( png, info, PNG_INFO_tRNS ) )
+ png_set_tRNS_to_alpha( png );
- // These color_type don't have an alpha channel then fill it with 0xff.
- if( color_type == PNG_COLOR_TYPE_RGB ||
- color_type == PNG_COLOR_TYPE_GRAY ||
- color_type == PNG_COLOR_TYPE_PALETTE )
- png_set_filler( png, 0xFF, PNG_FILLER_AFTER );
+ // These color_type don't have an alpha channel then fill it with 0xff.
+ if( color_type == PNG_COLOR_TYPE_RGB ||
+ color_type == PNG_COLOR_TYPE_GRAY ||
+ color_type == PNG_COLOR_TYPE_PALETTE )
+ png_set_filler( png, 0xFF, PNG_FILLER_AFTER );
- if( color_type == PNG_COLOR_TYPE_GRAY ||
- color_type == PNG_COLOR_TYPE_GRAY_ALPHA )
- png_set_gray_to_rgb( png );
+ if( color_type == PNG_COLOR_TYPE_GRAY ||
+ color_type == PNG_COLOR_TYPE_GRAY_ALPHA )
+ png_set_gray_to_rgb( png );
- png_read_update_info( png, info );
+ png_read_update_info( png, info );
#endif
- //Array of row pointers. One for every row.
- std::vector<png_bytep> rowPtrs(m_Desc.Height);
+ //Array of row pointers. One for every row.
+ std::vector<png_bytep> rowPtrs(m_Desc.Height);
- //Alocate a buffer with enough space. Align stride to 4 bytes
- m_Desc.RowStride = Align(m_Desc.Width * bit_depth * m_Desc.NumComponents / 8, 4u);
- m_pData->Resize( size_t{m_Desc.Height} * size_t{m_Desc.RowStride} );
- for( size_t i = 0; i < m_Desc.Height; i++ )
- rowPtrs[i] = reinterpret_cast<png_bytep>(m_pData->GetDataPtr()) + i * m_Desc.RowStride;
+ //Alocate a buffer with enough space. Align stride to 4 bytes
+ m_Desc.RowStride = Align(m_Desc.Width * bit_depth * m_Desc.NumComponents / 8, 4u);
+ m_pData->Resize( size_t{m_Desc.Height} * size_t{m_Desc.RowStride} );
+ for( size_t i = 0; i < m_Desc.Height; i++ )
+ rowPtrs[i] = reinterpret_cast<png_bytep>(m_pData->GetDataPtr()) + i * m_Desc.RowStride;
- //Read the imagedata and write it to the adresses pointed to
- //by rowptrs (in other words: our image databuffer)
- png_read_image( png, rowPtrs.data() );
+ //Read the imagedata and write it to the adresses pointed to
+ //by rowptrs (in other words: our image databuffer)
+ png_read_image( png, rowPtrs.data() );
- png_destroy_read_struct(&png, &info, (png_infopp)0);
- }
+ png_destroy_read_struct(&png, &info, (png_infopp)0);
+}
- struct my_jpeg_error_mgr {
- jpeg_error_mgr pub;
- char padding[8];
- jmp_buf setjmp_buffer;// for return to caller
- };
+struct my_jpeg_error_mgr {
+ jpeg_error_mgr pub;
+ char padding[8];
+ jmp_buf setjmp_buffer;// for return to caller
+};
- // Here's the routine that will replace the standard error_exit method:
- METHODDEF(void)
- my_error_exit (j_common_ptr cinfo)
- {
- // cinfo->err really points to a my_jpeg_error_mgr struct, so coerce pointer
- my_jpeg_error_mgr* myerr = (my_jpeg_error_mgr*) cinfo->err;
+// Here's the routine that will replace the standard error_exit method:
+METHODDEF(void)
+my_error_exit (j_common_ptr cinfo)
+{
+ // cinfo->err really points to a my_jpeg_error_mgr struct, so coerce pointer
+ my_jpeg_error_mgr* myerr = (my_jpeg_error_mgr*) cinfo->err;
- /* Always display the message. */
- /* We could postpone this until after returning, if we chose. */
- (*cinfo->err->output_message) (cinfo);
+ /* Always display the message. */
+ /* We could postpone this until after returning, if we chose. */
+ (*cinfo->err->output_message) (cinfo);
- // Return control to the setjmp point
- longjmp(myerr->setjmp_buffer, 1);
- }
+ // Return control to the setjmp point
+ longjmp(myerr->setjmp_buffer, 1);
+}
- void Image::LoadJpegFile( IDataBlob *pFileData, const ImageLoadInfo& LoadInfo )
- {
- // https://github.com/LuaDist/libjpeg/blob/master/example.c
+void Image::LoadJpegFile( IDataBlob *pFileData, const ImageLoadInfo& LoadInfo )
+{
+ // https://github.com/LuaDist/libjpeg/blob/master/example.c
- // This struct contains the JPEG decompression parameters and pointers to
- // working space (which is allocated as needed by the JPEG library).
- jpeg_decompress_struct cinfo;
+ // This struct contains the JPEG decompression parameters and pointers to
+ // working space (which is allocated as needed by the JPEG library).
+ jpeg_decompress_struct cinfo;
- // We use our private extension JPEG error handler.
- // Note that this struct must live as long as the main JPEG parameter
- // struct, to avoid dangling-pointer problems.
- my_jpeg_error_mgr jerr;
+ // We use our private extension JPEG error handler.
+ // Note that this struct must live as long as the main JPEG parameter
+ // struct, to avoid dangling-pointer problems.
+ my_jpeg_error_mgr jerr;
- // Step 1: allocate and initialize JPEG decompression object
+ // Step 1: allocate and initialize JPEG decompression object
- // We set up the normal JPEG error routines, then override error_exit.
- cinfo.err = jpeg_std_error( &jerr.pub );
- jerr.pub.error_exit = my_error_exit;
- // Establish the setjmp return context for my_error_exit to use.
- if( setjmp( jerr.setjmp_buffer ) )
- {
- // If we get here, the JPEG code has signaled an error.
- // We need to clean up the JPEG object, close the input file, and return.
- jpeg_destroy_decompress( &cinfo );
- LOG_ERROR_AND_THROW( "Failed to decompress JPEG image" );
- }
- // Now we can initialize the JPEG decompression object.
- jpeg_create_decompress( &cinfo );
+ // We set up the normal JPEG error routines, then override error_exit.
+ cinfo.err = jpeg_std_error( &jerr.pub );
+ jerr.pub.error_exit = my_error_exit;
+ // Establish the setjmp return context for my_error_exit to use.
+ if( setjmp( jerr.setjmp_buffer ) )
+ {
+ // If we get here, the JPEG code has signaled an error.
+ // We need to clean up the JPEG object, close the input file, and return.
+ jpeg_destroy_decompress( &cinfo );
+ LOG_ERROR_AND_THROW( "Failed to decompress JPEG image" );
+ }
+ // Now we can initialize the JPEG decompression object.
+ jpeg_create_decompress( &cinfo );
- // Step 2: specify data source
- jpeg_mem_src( &cinfo, reinterpret_cast<unsigned char*>(pFileData->GetDataPtr()), static_cast<unsigned long>(pFileData->GetSize()) );
+ // Step 2: specify data source
+ jpeg_mem_src( &cinfo, reinterpret_cast<unsigned char*>(pFileData->GetDataPtr()), static_cast<unsigned long>(pFileData->GetSize()) );
- // Step 3: read file parameters with jpeg_read_header()
- jpeg_read_header( &cinfo, TRUE );
- // We can ignore the return value from jpeg_read_header since
- // (a) suspension is not possible with the stdio data source, and
- // (b) we passed TRUE to reject a tables-only JPEG file as an error.
- // See libjpeg.txt for more info.
+ // Step 3: read file parameters with jpeg_read_header()
+ jpeg_read_header( &cinfo, TRUE );
+ // We can ignore the return value from jpeg_read_header since
+ // (a) suspension is not possible with the stdio data source, and
+ // (b) we passed TRUE to reject a tables-only JPEG file as an error.
+ // See libjpeg.txt for more info.
- // Step 4: set parameters for decompression
+ // Step 4: set parameters for decompression
- // In this example, we don't need to change any of the defaults set by
- // jpeg_read_header(), so we do nothing here.
+ // In this example, we don't need to change any of the defaults set by
+ // jpeg_read_header(), so we do nothing here.
- // Step 5: Start decompressor
+ // Step 5: Start decompressor
- jpeg_start_decompress( &cinfo );
- // We can ignore the return value since suspension is not possible
- // with the stdio data source.
+ jpeg_start_decompress( &cinfo );
+ // We can ignore the return value since suspension is not possible
+ // with the stdio data source.
- // We may need to do some setup of our own at this point before reading
- // the data. After jpeg_start_decompress() we have the correct scaled
- // output image dimensions available, as well as the output colormap
- // if we asked for color quantization.
+ // We may need to do some setup of our own at this point before reading
+ // the data. After jpeg_start_decompress() we have the correct scaled
+ // output image dimensions available, as well as the output colormap
+ // if we asked for color quantization.
- m_Desc.Width = cinfo.output_width;
- m_Desc.Height = cinfo.output_height;
- m_Desc.NumComponents = cinfo.output_components;
- m_Desc.RowStride = Align(m_Desc.Width * m_Desc.NumComponents, 4u);
- m_Desc.BitsPerPixel = 8 * m_Desc.NumComponents;
+ m_Desc.Width = cinfo.output_width;
+ m_Desc.Height = cinfo.output_height;
+ m_Desc.NumComponents = cinfo.output_components;
+ m_Desc.RowStride = Align(m_Desc.Width * m_Desc.NumComponents, 4u);
+ m_Desc.BitsPerPixel = 8 * m_Desc.NumComponents;
- m_pData->Resize(size_t{m_Desc.RowStride} * size_t{m_Desc.Height});
- // Step 6: while (scan lines remain to be read)
- // jpeg_read_scanlines(...);
+ m_pData->Resize(size_t{m_Desc.RowStride} * size_t{m_Desc.Height});
+ // Step 6: while (scan lines remain to be read)
+ // jpeg_read_scanlines(...);
- // Here we use the library's state variable cinfo.output_scanline as the
- // loop counter, so that we don't have to keep track ourselves.
- while( cinfo.output_scanline < cinfo.output_height ) {
- // jpeg_read_scanlines expects an array of pointers to scanlines.
- // Here the array is only one element long, but you could ask for
- // more than one scanline at a time if that's more convenient.
+ // Here we use the library's state variable cinfo.output_scanline as the
+ // loop counter, so that we don't have to keep track ourselves.
+ while( cinfo.output_scanline < cinfo.output_height ) {
+ // jpeg_read_scanlines expects an array of pointers to scanlines.
+ // Here the array is only one element long, but you could ask for
+ // more than one scanline at a time if that's more convenient.
- auto *pDstScanline = reinterpret_cast<Uint8*>( m_pData->GetDataPtr() ) + size_t{cinfo.output_scanline} * size_t{m_Desc.RowStride};
- JSAMPROW RowPtrs[] = { reinterpret_cast<JSAMPROW>(pDstScanline) };
- jpeg_read_scanlines( &cinfo, RowPtrs, 1 );
- }
+ auto *pDstScanline = reinterpret_cast<Uint8*>( m_pData->GetDataPtr() ) + size_t{cinfo.output_scanline} * size_t{m_Desc.RowStride};
+ JSAMPROW RowPtrs[] = { reinterpret_cast<JSAMPROW>(pDstScanline) };
+ jpeg_read_scanlines( &cinfo, RowPtrs, 1 );
+ }
- // Step 7: Finish decompression
+ // Step 7: Finish decompression
- jpeg_finish_decompress( &cinfo );
- // We can ignore the return value since suspension is not possible
- // with the stdio data source.
+ jpeg_finish_decompress( &cinfo );
+ // We can ignore the return value since suspension is not possible
+ // with the stdio data source.
- // Step 8: Release JPEG decompression object
+ // Step 8: Release JPEG decompression object
- // This is an important step since it will release a good deal of memory.
- jpeg_destroy_decompress( &cinfo );
+ // This is an important step since it will release a good deal of memory.
+ jpeg_destroy_decompress( &cinfo );
- // At this point you may want to check to see whether any corrupt-data
- // warnings occurred (test whether jerr.pub.num_warnings is nonzero).
- }
+ // At this point you may want to check to see whether any corrupt-data
+ // warnings occurred (test whether jerr.pub.num_warnings is nonzero).
+}
- Image::Image( IReferenceCounters *pRefCounters,
- IDataBlob *pFileData,
- const ImageLoadInfo& LoadInfo ) :
- TBase(pRefCounters),
- m_pData( MakeNewRCObj<DataBlobImpl>()(0) )
+Image::Image( IReferenceCounters *pRefCounters,
+ IDataBlob *pFileData,
+ const ImageLoadInfo& LoadInfo ) :
+ TBase(pRefCounters),
+ m_pData( MakeNewRCObj<DataBlobImpl>()(0) )
+{
+ if( LoadInfo.Format == EImageFileFormat::tiff )
{
- if( LoadInfo.Format == EImageFileFormat::tiff )
- {
- LoadTiffFile(pFileData, LoadInfo );
- }
- else if( LoadInfo.Format == EImageFileFormat::png )
- {
- LoadPngFile(pFileData, LoadInfo );
- }
- else if( LoadInfo.Format == EImageFileFormat::jpeg )
- {
- LoadJpegFile(pFileData, LoadInfo );
- }
+ LoadTiffFile(pFileData, LoadInfo );
}
-
- void Image::CreateFromDataBlob(IDataBlob *pFileData,
- const ImageLoadInfo& LoadInfo,
- Image **ppImage)
+ else if( LoadInfo.Format == EImageFileFormat::png )
{
- *ppImage = MakeNewRCObj<Image>()(pFileData, LoadInfo);
- (*ppImage)->AddRef();
+ LoadPngFile(pFileData, LoadInfo );
}
+ else if( LoadInfo.Format == EImageFileFormat::jpeg )
+ {
+ LoadJpegFile(pFileData, LoadInfo );
+ }
+}
+
+void Image::CreateFromDataBlob(IDataBlob *pFileData,
+ const ImageLoadInfo& LoadInfo,
+ Image **ppImage)
+{
+ *ppImage = MakeNewRCObj<Image>()(pFileData, LoadInfo);
+ (*ppImage)->AddRef();
+}
- static void WritePng(const Uint8* pData, Uint32 Width, Uint32 Height, Uint32 Stride, int PngColorType, IDataBlob* pEncodedData)
+static void WritePng(const Uint8* pData, Uint32 Width, Uint32 Height, Uint32 Stride, int PngColorType, IDataBlob* pEncodedData)
+{
+ struct PngWrapper
{
- struct PngWrapper
+ PngWrapper()
{
- PngWrapper()
- {
- strct = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- VERIFY(strct, "png_create_write_struct() failed");
- info = png_create_info_struct(strct);
- VERIFY(info, "png_create_info_struct() failed");
- }
+ strct = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ VERIFY(strct, "png_create_write_struct() failed");
+ info = png_create_info_struct(strct);
+ VERIFY(info, "png_create_info_struct() failed");
+ }
- ~PngWrapper()
- {
- if (strct)
- {
- png_destroy_write_struct(&strct, &info);
- }
+ ~PngWrapper()
+ {
+ if (strct)
+ {
+ png_destroy_write_struct(&strct, &info);
}
+ }
- png_struct* strct = nullptr;
- png_info* info = nullptr;
- }Png;
-
- VERIFY(setjmp(png_jmpbuf(Png.strct)) == 0, "setjmp(png_jmpbuf(p) failed");
- png_set_IHDR(Png.strct, Png.info, Width, Height, 8,
- PngColorType,
- PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_DEFAULT,
- PNG_FILTER_TYPE_DEFAULT);
- //png_set_compression_level(p, 1);
- std::vector<Uint8*> rows(Height);
- for (size_t y = 0; y < Height; ++y)
- rows[y] = const_cast<Uint8*>(pData) + y * Stride;
- png_set_rows(Png.strct, Png.info, rows.data());
+ png_struct* strct = nullptr;
+ png_info* info = nullptr;
+ }Png;
+
+ VERIFY(setjmp(png_jmpbuf(Png.strct)) == 0, "setjmp(png_jmpbuf(p) failed");
+ png_set_IHDR(Png.strct, Png.info, Width, Height, 8,
+ PngColorType,
+ PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_DEFAULT,
+ PNG_FILTER_TYPE_DEFAULT);
+ //png_set_compression_level(p, 1);
+ std::vector<Uint8*> rows(Height);
+ for (size_t y = 0; y < Height; ++y)
+ rows[y] = const_cast<Uint8*>(pData) + y * Stride;
+ png_set_rows(Png.strct, Png.info, rows.data());
- auto PngWriteCallback = [](png_structp png_ptr, png_bytep data, png_size_t length)
- {
- auto* pEncodedData = reinterpret_cast<IDataBlob*>(png_get_io_ptr(png_ptr));
- pEncodedData->Resize(pEncodedData->GetSize() + length);
- auto* pBytes = reinterpret_cast<Uint8*>(pEncodedData->GetDataPtr());
- memcpy(pBytes + pEncodedData->GetSize() - length, data, length);
- };
-
- png_set_write_fn(Png.strct, pEncodedData, PngWriteCallback, NULL);
- png_write_png(Png.strct, Png.info, PNG_TRANSFORM_IDENTITY, NULL);
- }
+ auto PngWriteCallback = [](png_structp png_ptr, png_bytep data, png_size_t length)
+ {
+ auto* pEncodedData = reinterpret_cast<IDataBlob*>(png_get_io_ptr(png_ptr));
+ pEncodedData->Resize(pEncodedData->GetSize() + length);
+ auto* pBytes = reinterpret_cast<Uint8*>(pEncodedData->GetDataPtr());
+ memcpy(pBytes + pEncodedData->GetSize() - length, data, length);
+ };
+
+ png_set_write_fn(Png.strct, pEncodedData, PngWriteCallback, NULL);
+ png_write_png(Png.strct, Png.info, PNG_TRANSFORM_IDENTITY, NULL);
+}
- static void WriteJPEG(JSAMPLE* pRGBData, Uint32 Width, Uint32 Height, int quality, IDataBlob* pEncodedData)
+static void WriteJPEG(JSAMPLE* pRGBData, Uint32 Width, Uint32 Height, int quality, IDataBlob* pEncodedData)
+{
+ /* This struct contains the JPEG compression parameters and pointers to
+ * working space (which is allocated as needed by the JPEG library).
+ * It is possible to have several such structures, representing multiple
+ * compression/decompression processes, in existence at once. We refer
+ * to any one struct (and its associated working data) as a "JPEG object".
+ */
+ jpeg_compress_struct cinfo;
+
+ /* This struct represents a JPEG error handler. It is declared separately
+ * because applications often want to supply a specialized error handler
+ * (see the second half of this file for an example). But here we just
+ * take the easy way out and use the standard error handler, which will
+ * print a message on stderr and call exit() if compression fails.
+ * Note that this struct must live as long as the main JPEG parameter
+ * struct, to avoid dangling-pointer problems.
+ */
+ jpeg_error_mgr jerr;
+
+ /* Step 1: allocate and initialize JPEG compression object */
+
+ /* We have to set up the error handler first, in case the initialization
+ * step fails. (Unlikely, but it could happen if you are out of memory.)
+ * This routine fills in the contents of struct jerr, and returns jerr's
+ * address which we place into the link field in cinfo.
+ */
+ cinfo.err = jpeg_std_error(&jerr);
+ /* Now we can initialize the JPEG compression object. */
+ jpeg_create_compress(&cinfo);
+
+ /* Step 2: specify data destination (memory) */
+ /* Note: steps 2 and 3 can be done in either order. */
+ unsigned char *mem = NULL;
+ unsigned long mem_size = 0;
+ jpeg_mem_dest(&cinfo, &mem, &mem_size);
+
+ /* Step 3: set parameters for compression */
+
+ /* First we supply a description of the input image.
+ * Four fields of the cinfo struct must be filled in:
+ */
+ cinfo.image_width = Width; /* image width and height, in pixels */
+ cinfo.image_height = Height;
+ cinfo.input_components = 3; /* # of color components per pixel */
+ cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
+ /* Now use the library's routine to set default compression parameters.
+ * (You must set at least cinfo.in_color_space before calling this,
+ * since the defaults depend on the source color space.)
+ */
+ jpeg_set_defaults(&cinfo);
+ /* Now you can set any non-default parameters you wish to.
+ * Here we just illustrate the use of quality (quantization table) scaling:
+ */
+ jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
+
+ /* Step 4: Start compressor */
+
+ /* TRUE ensures that we will write a complete interchange-JPEG file.
+ * Pass TRUE unless you are very sure of what you're doing.
+ */
+ jpeg_start_compress(&cinfo, TRUE);
+
+ /* Step 5: while (scan lines remain to be written) */
+ /* jpeg_write_scanlines(...); */
+
+ /* Here we use the library's state variable cinfo.next_scanline as the
+ * loop counter, so that we don't have to keep track ourselves.
+ * To keep things simple, we pass one scanline per call; you can pass
+ * more if you wish, though.
+ */
+ auto row_stride = Width * 3; /* JSAMPLEs per row in image_buffer */
+
+ while (cinfo.next_scanline < cinfo.image_height)
{
- /* This struct contains the JPEG compression parameters and pointers to
- * working space (which is allocated as needed by the JPEG library).
- * It is possible to have several such structures, representing multiple
- * compression/decompression processes, in existence at once. We refer
- * to any one struct (and its associated working data) as a "JPEG object".
- */
- jpeg_compress_struct cinfo;
-
- /* This struct represents a JPEG error handler. It is declared separately
- * because applications often want to supply a specialized error handler
- * (see the second half of this file for an example). But here we just
- * take the easy way out and use the standard error handler, which will
- * print a message on stderr and call exit() if compression fails.
- * Note that this struct must live as long as the main JPEG parameter
- * struct, to avoid dangling-pointer problems.
- */
- jpeg_error_mgr jerr;
-
- /* Step 1: allocate and initialize JPEG compression object */
-
- /* We have to set up the error handler first, in case the initialization
- * step fails. (Unlikely, but it could happen if you are out of memory.)
- * This routine fills in the contents of struct jerr, and returns jerr's
- * address which we place into the link field in cinfo.
- */
- cinfo.err = jpeg_std_error(&jerr);
- /* Now we can initialize the JPEG compression object. */
- jpeg_create_compress(&cinfo);
-
- /* Step 2: specify data destination (memory) */
- /* Note: steps 2 and 3 can be done in either order. */
- unsigned char *mem = NULL;
- unsigned long mem_size = 0;
- jpeg_mem_dest(&cinfo, &mem, &mem_size);
-
- /* Step 3: set parameters for compression */
-
- /* First we supply a description of the input image.
- * Four fields of the cinfo struct must be filled in:
- */
- cinfo.image_width = Width; /* image width and height, in pixels */
- cinfo.image_height = Height;
- cinfo.input_components = 3; /* # of color components per pixel */
- cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
- /* Now use the library's routine to set default compression parameters.
- * (You must set at least cinfo.in_color_space before calling this,
- * since the defaults depend on the source color space.)
- */
- jpeg_set_defaults(&cinfo);
- /* Now you can set any non-default parameters you wish to.
- * Here we just illustrate the use of quality (quantization table) scaling:
- */
- jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
-
- /* Step 4: Start compressor */
-
- /* TRUE ensures that we will write a complete interchange-JPEG file.
- * Pass TRUE unless you are very sure of what you're doing.
- */
- jpeg_start_compress(&cinfo, TRUE);
-
- /* Step 5: while (scan lines remain to be written) */
- /* jpeg_write_scanlines(...); */
-
- /* Here we use the library's state variable cinfo.next_scanline as the
- * loop counter, so that we don't have to keep track ourselves.
- * To keep things simple, we pass one scanline per call; you can pass
- * more if you wish, though.
- */
- auto row_stride = Width * 3; /* JSAMPLEs per row in image_buffer */
-
- while (cinfo.next_scanline < cinfo.image_height)
- {
- /* jpeg_write_scanlines expects an array of pointers to scanlines.
- * Here the array is only one element long, but you could pass
- * more than one scanline at a time if that's more convenient.
- */
- JSAMPROW row_pointer[1] = { &pRGBData[cinfo.next_scanline * row_stride] };
- jpeg_write_scanlines(&cinfo, row_pointer, 1);
- }
+ /* jpeg_write_scanlines expects an array of pointers to scanlines.
+ * Here the array is only one element long, but you could pass
+ * more than one scanline at a time if that's more convenient.
+ */
+ JSAMPROW row_pointer[1] = { &pRGBData[cinfo.next_scanline * row_stride] };
+ jpeg_write_scanlines(&cinfo, row_pointer, 1);
+ }
- /* Step 6: Finish compression */
- jpeg_finish_compress(&cinfo);
+ /* Step 6: Finish compression */
+ jpeg_finish_compress(&cinfo);
- pEncodedData->Resize(mem_size);
- memcpy(pEncodedData->GetDataPtr(), mem, mem_size);
+ pEncodedData->Resize(mem_size);
+ memcpy(pEncodedData->GetDataPtr(), mem, mem_size);
- /* After finish_compress, we can free memory buffer. */
- free(mem);
+ /* After finish_compress, we can free memory buffer. */
+ free(mem);
- /* Step 7: release JPEG compression object */
+ /* Step 7: release JPEG compression object */
- /* This is an important step since it will release a good deal of memory. */
- jpeg_destroy_compress(&cinfo);
- }
+ /* This is an important step since it will release a good deal of memory. */
+ jpeg_destroy_compress(&cinfo);
+}
- static const std::array<Uint8, 4> GetRGBAOffsets(TEXTURE_FORMAT Format)
+static const std::array<Uint8, 4> GetRGBAOffsets(TEXTURE_FORMAT Format)
+{
+ switch(Format)
{
- switch(Format)
- {
- case TEX_FORMAT_BGRA8_TYPELESS:
- case TEX_FORMAT_BGRA8_UNORM:
- case TEX_FORMAT_BGRA8_UNORM_SRGB:
- return {{2,1,0,3}};
- default:
- return {{0,1,2,3}};
- }
+ case TEX_FORMAT_BGRA8_TYPELESS:
+ case TEX_FORMAT_BGRA8_UNORM:
+ case TEX_FORMAT_BGRA8_UNORM_SRGB:
+ return {{2,1,0,3}};
+ default:
+ return {{0,1,2,3}};
}
+}
- std::vector<Uint8> Image::ConvertImageData(Uint32 Width,
- Uint32 Height,
- const Uint8* pData,
- Uint32 Stride,
- TEXTURE_FORMAT SrcFormat,
- TEXTURE_FORMAT DstFormat,
- bool KeepAlpha)
- {
- const auto& SrcFmtAttribs = GetTextureFormatAttribs(SrcFormat);
- const auto& DstFmtAttribs = GetTextureFormatAttribs(DstFormat);
- VERIFY(SrcFmtAttribs.ComponentSize == 1, "Only 8-bit formats are currently supported");
- VERIFY(DstFmtAttribs.ComponentSize == 1, "Only 8-bit formats are currently supported");
+std::vector<Uint8> Image::ConvertImageData(Uint32 Width,
+ Uint32 Height,
+ const Uint8* pData,
+ Uint32 Stride,
+ TEXTURE_FORMAT SrcFormat,
+ TEXTURE_FORMAT DstFormat,
+ bool KeepAlpha)
+{
+ const auto& SrcFmtAttribs = GetTextureFormatAttribs(SrcFormat);
+ const auto& DstFmtAttribs = GetTextureFormatAttribs(DstFormat);
+ VERIFY(SrcFmtAttribs.ComponentSize == 1, "Only 8-bit formats are currently supported");
+ VERIFY(DstFmtAttribs.ComponentSize == 1, "Only 8-bit formats are currently supported");
- auto NumDstComponents = SrcFmtAttribs.NumComponents;
- if (!KeepAlpha)
- NumDstComponents = std::min(NumDstComponents, Uint8{3});
+ auto NumDstComponents = SrcFmtAttribs.NumComponents;
+ if (!KeepAlpha)
+ NumDstComponents = std::min(NumDstComponents, Uint8{3});
- auto SrcOffsets = GetRGBAOffsets(SrcFormat);
- auto DstOffsets = GetRGBAOffsets(DstFormat);
+ auto SrcOffsets = GetRGBAOffsets(SrcFormat);
+ auto DstOffsets = GetRGBAOffsets(DstFormat);
- std::vector<Uint8> ConvertedData(DstFmtAttribs.ComponentSize * NumDstComponents * Width * Height);
+ std::vector<Uint8> ConvertedData(DstFmtAttribs.ComponentSize * NumDstComponents * Width * Height);
- for (Uint32 j=0; j < Height; ++j)
+ for (Uint32 j=0; j < Height; ++j)
+ {
+ for (Uint32 i=0; i < Width; ++i)
{
- for (Uint32 i=0; i < Width; ++i)
+ for (Uint32 c = 0; c < NumDstComponents; ++c)
{
- for (Uint32 c = 0; c < NumDstComponents; ++c)
- {
- ConvertedData[j * Width * NumDstComponents + i*NumDstComponents + DstOffsets[c]] =
- pData[j * Stride + i*SrcFmtAttribs.NumComponents + SrcOffsets[c]];
- }
+ ConvertedData[j * Width * NumDstComponents + i*NumDstComponents + DstOffsets[c]] =
+ pData[j * Stride + i*SrcFmtAttribs.NumComponents + SrcOffsets[c]];
}
}
-
- return ConvertedData;
}
+ return ConvertedData;
+}
+
- void Image::Encode(const EncodeInfo& Info, IDataBlob** ppEncodedData)
+void Image::Encode(const EncodeInfo& Info, IDataBlob** ppEncodedData)
+{
+ RefCntAutoPtr<IDataBlob> pEncodedData(MakeNewRCObj<DataBlobImpl>()(0));
+ if (Info.FileFormat == EImageFileFormat::jpeg)
+ {
+ auto RGBData = ConvertImageData(Info.Width, Info.Height, reinterpret_cast<const Uint8*>(Info.pData), Info.Stride, Info.TexFormat, TEX_FORMAT_RGBA8_UNORM, false);
+ WriteJPEG(RGBData.data(), Info.Width, Info.Height, Info.JpegQuality, pEncodedData);
+ }
+ else if (Info.FileFormat == EImageFileFormat::png)
{
- RefCntAutoPtr<IDataBlob> pEncodedData(MakeNewRCObj<DataBlobImpl>()(0));
- if (Info.FileFormat == EImageFileFormat::jpeg)
+ const auto* pData = reinterpret_cast<const Uint8*>(Info.pData);
+ auto Stride = Info.Stride;
+ std::vector<Uint8> ConvertedData;
+ if ( !((Info.TexFormat == TEX_FORMAT_RGBA8_UNORM || Info.TexFormat == TEX_FORMAT_RGBA8_UNORM_SRGB) && Info.KeepAlpha) )
{
- auto RGBData = ConvertImageData(Info.Width, Info.Height, reinterpret_cast<const Uint8*>(Info.pData), Info.Stride, Info.TexFormat, TEX_FORMAT_RGBA8_UNORM, false);
- WriteJPEG(RGBData.data(), Info.Width, Info.Height, Info.JpegQuality, pEncodedData);
+ ConvertedData = ConvertImageData(Info.Width, Info.Height, reinterpret_cast<const Uint8*>(Info.pData), Info.Stride, Info.TexFormat, TEX_FORMAT_RGBA8_UNORM, Info.KeepAlpha);
+ pData = ConvertedData.data();
+ Stride = Info.Width * (Info.KeepAlpha ? 4 : 3);
}
- else if (Info.FileFormat == EImageFileFormat::png)
- {
- const auto* pData = reinterpret_cast<const Uint8*>(Info.pData);
- auto Stride = Info.Stride;
- std::vector<Uint8> ConvertedData;
- if ( !((Info.TexFormat == TEX_FORMAT_RGBA8_UNORM || Info.TexFormat == TEX_FORMAT_RGBA8_UNORM_SRGB) && Info.KeepAlpha) )
- {
- ConvertedData = ConvertImageData(Info.Width, Info.Height, reinterpret_cast<const Uint8*>(Info.pData), Info.Stride, Info.TexFormat, TEX_FORMAT_RGBA8_UNORM, Info.KeepAlpha);
- pData = ConvertedData.data();
- Stride = Info.Width * (Info.KeepAlpha ? 4 : 3);
- }
- WritePng(pData, Info.Width, Info.Height, Stride, Info.KeepAlpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB, pEncodedData);
- }
- else
- {
- UNSUPPORTED("Unsupported image file format");
- }
- pEncodedData->QueryInterface(IID_DataBlob, reinterpret_cast<IObject**>(ppEncodedData));
+ WritePng(pData, Info.Width, Info.Height, Stride, Info.KeepAlpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB, pEncodedData);
+ }
+ else
+ {
+ UNSUPPORTED("Unsupported image file format");
}
+ pEncodedData->QueryInterface(IID_DataBlob, reinterpret_cast<IObject**>(ppEncodedData));
}
+
+} // namespace Diligent