mirror of
				https://github.com/yuzu-emu/FasTC.git
				synced 2025-11-04 11:15:01 +00:00 
			
		
		
		
	Fleshed out some more of the library
This commit is contained in:
		
							parent
							
								
									39d7f2c942
								
							
						
					
					
						commit
						a076d1efb8
					
				| 
						 | 
					@ -3,3 +3,4 @@ PROJECT(TexC)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ADD_SUBDIRECTORY(BPTCEncoder)
 | 
					ADD_SUBDIRECTORY(BPTCEncoder)
 | 
				
			||||||
ADD_SUBDIRECTORY(IO)
 | 
					ADD_SUBDIRECTORY(IO)
 | 
				
			||||||
 | 
					ADD_SUBDIRECTORY(Core)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,15 +1,21 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SET( SOURCES
 | 
					SET( SOURCES
 | 
				
			||||||
	"src/TexComp.cpp"
 | 
						"src/TexComp.cpp"
 | 
				
			||||||
 | 
						"src/CompressedImage.cpp"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SET( HEADERS
 | 
					SET( HEADERS
 | 
				
			||||||
	"include/TexComp.h"
 | 
						"include/TexComp.h"
 | 
				
			||||||
 | 
						"include/CompressedImage.h"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					INCLUDE_DIRECTORIES( ${TexC_BINARY_DIR}/IO/include )
 | 
				
			||||||
 | 
					INCLUDE_DIRECTORIES( ${TexC_SOURCE_DIR}/IO/include )
 | 
				
			||||||
INCLUDE_DIRECTORIES( ${TexC_SOURCE_DIR}/Core/include )
 | 
					INCLUDE_DIRECTORIES( ${TexC_SOURCE_DIR}/Core/include )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ADD_LIBRARY( TexCompCore
 | 
					ADD_LIBRARY( TexCompCore
 | 
				
			||||||
	${HEADERS}
 | 
						${HEADERS}
 | 
				
			||||||
	${SOURCES}
 | 
						${SOURCES}
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TARGET_LINK_LIBRARIES( TexCompCore TexCompIO )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										34
									
								
								Core/include/CompressedImage.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								Core/include/CompressedImage.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,34 @@
 | 
				
			||||||
 | 
					#ifndef _COMPRESSED_IMAGE_H_
 | 
				
			||||||
 | 
					#define _COMPRESSED_IMAGE_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum ECompressionFormat {
 | 
				
			||||||
 | 
					  eCompressionFormat_DXT1,
 | 
				
			||||||
 | 
					  eCompressionFormat_DXT5,
 | 
				
			||||||
 | 
					  eCompressionFormat_BPTC,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  kNumCompressionFormats
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CompressedImage {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  unsigned char *m_Data;
 | 
				
			||||||
 | 
					  unsigned int m_DataSz;
 | 
				
			||||||
 | 
					  unsigned int m_Width;
 | 
				
			||||||
 | 
					  unsigned int m_Height;
 | 
				
			||||||
 | 
					  ECompressionFormat m_Format;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void InitData(const unsigned char *withData);
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  CompressedImage(
 | 
				
			||||||
 | 
					    const unsigned int width, 
 | 
				
			||||||
 | 
					    const unsigned int height, 
 | 
				
			||||||
 | 
					    const ECompressionFormat format, 
 | 
				
			||||||
 | 
					    const unsigned char *data
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  CompressedImage( const CompressedImage &other );
 | 
				
			||||||
 | 
					  ~CompressedImage();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // _COMPRESSED_IMAGE_H_
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,27 @@
 | 
				
			||||||
#ifndef _TEX_COMP_H_
 | 
					#ifndef _TEX_COMP_H_
 | 
				
			||||||
#define _TEX_COMP_H_
 | 
					#define _TEX_COMP_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "ImageFile.h"
 | 
				
			||||||
 | 
					#include "CompressedImage.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct SCompressionSettings {
 | 
				
			||||||
 | 
					  SCompressionSettings(); // defaults
 | 
				
			||||||
 | 
					  ECompressionFormat format; 
 | 
				
			||||||
 | 
					  bool bUseSIMD;
 | 
				
			||||||
 | 
					  int iNumThreads;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern void CompressImage(
 | 
				
			||||||
 | 
					  const ImageFile &, 
 | 
				
			||||||
 | 
					  CompressedImage &, 
 | 
				
			||||||
 | 
					  const SCompressionSettings &settings
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef void (* CompressionFunc)(
 | 
				
			||||||
 | 
					  const unsigned char *inData,
 | 
				
			||||||
 | 
					  unsigned char *outData,
 | 
				
			||||||
 | 
					  unsigned int width,
 | 
				
			||||||
 | 
					  unsigned int height
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif //_TEX_COMP_H_
 | 
					#endif //_TEX_COMP_H_
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										50
									
								
								Core/src/CompressedImage.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								Core/src/CompressedImage.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,50 @@
 | 
				
			||||||
 | 
					#include "CompressedImage.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CompressedImage::CompressedImage( const CompressedImage &other )
 | 
				
			||||||
 | 
					  : m_Width(other.m_Width)
 | 
				
			||||||
 | 
					  , m_Height(other.m_Height)
 | 
				
			||||||
 | 
					  , m_Format(other.m_Format)
 | 
				
			||||||
 | 
					  , m_Data(0)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  InitData(other.m_Data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CompressedImage::CompressedImage(
 | 
				
			||||||
 | 
					  const unsigned int width,				 
 | 
				
			||||||
 | 
					  const unsigned int height,
 | 
				
			||||||
 | 
					  const ECompressionFormat format,
 | 
				
			||||||
 | 
					  const unsigned char *data
 | 
				
			||||||
 | 
					) 
 | 
				
			||||||
 | 
					: m_Width(width)
 | 
				
			||||||
 | 
					, m_Height(height)
 | 
				
			||||||
 | 
					, m_Format(format)
 | 
				
			||||||
 | 
					, m_Data(0)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  InitData(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CompressedImage::InitData(const unsigned char *withData) {
 | 
				
			||||||
 | 
					  unsigned int dataSz = 0;
 | 
				
			||||||
 | 
					  int uncompDataSz = m_Width * m_Height * 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  switch(m_Format) {
 | 
				
			||||||
 | 
					    case eCompressionFormat_DXT1: dataSz = uncompDataSz / 8; break;
 | 
				
			||||||
 | 
					    case eCompressionFormat_DXT5: dataSz = uncompDataSz / 4; break;
 | 
				
			||||||
 | 
					    case eCompressionFormat_BPTC: dataSz = uncompDataSz / 4; break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  if(dataSz > 0) {
 | 
				
			||||||
 | 
					    m_Data = new unsigned char[dataSz];
 | 
				
			||||||
 | 
					    memcpy(m_Data, withData, dataSz);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CompressedImage::~CompressedImage() {
 | 
				
			||||||
 | 
					  if(m_Data) {
 | 
				
			||||||
 | 
					    delete [] m_Data;
 | 
				
			||||||
 | 
					    m_Data = NULL;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1 +1,55 @@
 | 
				
			||||||
#include "TexComp.h"
 | 
					#include "TexComp.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SCompressionSettings:: SCompressionSettings()
 | 
				
			||||||
 | 
					  : format(eCompressionFormat_BPTC)
 | 
				
			||||||
 | 
					  , bUseSIMD(false)
 | 
				
			||||||
 | 
					  , iNumThreads(1)
 | 
				
			||||||
 | 
					{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static CompressionFunc ChooseFuncFromSettings(const SCompressionSettings &s) {
 | 
				
			||||||
 | 
					  return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void ReportError(const char *msg) {
 | 
				
			||||||
 | 
					  fprintf(stderr, "TexComp -- %s\n", msg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CompressImage(
 | 
				
			||||||
 | 
					  const ImageFile &img, 
 | 
				
			||||||
 | 
					  CompressedImage &outImg, 
 | 
				
			||||||
 | 
					  const SCompressionSettings &settings
 | 
				
			||||||
 | 
					) { 
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  const unsigned int dataSz = img.GetWidth() * img.GetHeight() * 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Allocate data based on the compression method
 | 
				
			||||||
 | 
					  int cmpDataSz = 0;
 | 
				
			||||||
 | 
					  switch(settings.format) {
 | 
				
			||||||
 | 
					    case eCompressionFormat_DXT1: cmpDataSz = dataSz / 8;
 | 
				
			||||||
 | 
					    case eCompressionFormat_DXT5: cmpDataSz = dataSz / 4;
 | 
				
			||||||
 | 
					    case eCompressionFormat_BPTC: cmpDataSz = dataSz / 4;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if(cmpDataSz == 0) {
 | 
				
			||||||
 | 
					    ReportError("Unknown compression format");
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  unsigned char *cmpData = new unsigned char[cmpDataSz];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  CompressionFunc f = ChooseFuncFromSettings(settings);
 | 
				
			||||||
 | 
					  if(f) {
 | 
				
			||||||
 | 
					    (*f)(img.GetPixels(), cmpData, img.GetWidth(), img.GetHeight());
 | 
				
			||||||
 | 
					    outImg = CompressedImage(img.GetWidth(), img.GetHeight(), settings.format, cmpData);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else {
 | 
				
			||||||
 | 
					    ReportError("Could not find adequate compression function for specified settings");
 | 
				
			||||||
 | 
					    // return
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Cleanup
 | 
				
			||||||
 | 
					  delete [] cmpData;
 | 
				
			||||||
 | 
					} 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,7 +12,6 @@ FIND_PACKAGE( PNG )
 | 
				
			||||||
IF( PNG_FOUND )
 | 
					IF( PNG_FOUND )
 | 
				
			||||||
	INCLUDE_DIRECTORIES( ${PNG_INCLUDE_DIR} )
 | 
						INCLUDE_DIRECTORIES( ${PNG_INCLUDE_DIR} )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
	SET( SOURCES ${SOURCES} "src/ImageLoaderPNG.cpp" )
 | 
						SET( SOURCES ${SOURCES} "src/ImageLoaderPNG.cpp" )
 | 
				
			||||||
	SET( HEADERS ${HEADERS} "src/ImageLoaderPNG.h" )
 | 
						SET( HEADERS ${HEADERS} "src/ImageLoaderPNG.h" )
 | 
				
			||||||
ENDIF()
 | 
					ENDIF()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,16 +62,19 @@ class ImageLoader {
 | 
				
			||||||
  virtual bool ReadData() = 0;
 | 
					  virtual bool ReadData() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int GetRedChannelPrecision() const { return m_RedChannelPrecision; }
 | 
					  int GetRedChannelPrecision() const { return m_RedChannelPrecision; }
 | 
				
			||||||
  unsigned char * GetRedPixelData() const { return m_RedData; }
 | 
					  const unsigned char * GetRedPixelData() const { return m_RedData; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int GetGreenChannelPrecision() const { return m_GreenChannelPrecision; }
 | 
					  int GetGreenChannelPrecision() const { return m_GreenChannelPrecision; }
 | 
				
			||||||
  unsigned char * GetGreenPixelData() const { return m_GreenData; }
 | 
					  const unsigned char * GetGreenPixelData() const { return m_GreenData; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int GetBlueChannelPrecision() const { return m_BlueChannelPrecision; }
 | 
					  int GetBlueChannelPrecision() const { return m_BlueChannelPrecision; }
 | 
				
			||||||
  unsigned char * GetBluePixelData() const { return m_BlueData; }
 | 
					  const unsigned char * GetBluePixelData() const { return m_BlueData; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int GetAlphaChannelPrecision() const { return m_AlphaChannelPrecision; }
 | 
					  int GetAlphaChannelPrecision() const { return m_AlphaChannelPrecision; }
 | 
				
			||||||
  unsigned char * GetAlphaPixelData() const { return m_AlphaData; }
 | 
					  const unsigned char * GetAlphaPixelData() const { return m_AlphaData; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int GetWidth() const { return m_Width; }
 | 
				
			||||||
 | 
					  int GetHeight() const { return m_Height; }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#cmakedefine PNG_FOUND
 | 
					#cmakedefine PNG_FOUND
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <limits.h>
 | 
				
			||||||
#include <assert.h>
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "ImageFile.h"
 | 
					#include "ImageFile.h"
 | 
				
			||||||
| 
						 | 
					@ -9,6 +10,101 @@
 | 
				
			||||||
#  include "ImageLoaderPNG.h"
 | 
					#  include "ImageLoaderPNG.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//////////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Static helper functions
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//////////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void ReportError(const char *msg) {
 | 
				
			||||||
 | 
					  fprintf(stderr, "ImageFile -- %s\n", msg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					static inline T abs(const T &a) {
 | 
				
			||||||
 | 
					  return a > 0? a : -a;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					static inline T min(const T &a, const T &b) {
 | 
				
			||||||
 | 
					  return (a < b)? a : b;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static unsigned int GetChannelForPixel(
 | 
				
			||||||
 | 
					  const ImageLoader *loader, 
 | 
				
			||||||
 | 
					  unsigned int x, unsigned int y,
 | 
				
			||||||
 | 
					  int ch
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					  unsigned int prec;
 | 
				
			||||||
 | 
					  const unsigned char *data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  switch(ch) {
 | 
				
			||||||
 | 
					  case 0:
 | 
				
			||||||
 | 
					    prec = loader->GetRedChannelPrecision();
 | 
				
			||||||
 | 
					    data = loader->GetRedPixelData();
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  case 1:
 | 
				
			||||||
 | 
					    prec = loader->GetGreenChannelPrecision();
 | 
				
			||||||
 | 
					    data = loader->GetGreenPixelData();
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  case 2:
 | 
				
			||||||
 | 
					    prec = loader->GetBlueChannelPrecision();
 | 
				
			||||||
 | 
					    data = loader->GetBluePixelData();
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  case 3:
 | 
				
			||||||
 | 
					    prec = loader->GetAlphaChannelPrecision();
 | 
				
			||||||
 | 
					    data = loader->GetAlphaPixelData();
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  default:
 | 
				
			||||||
 | 
					    ReportError("Unspecified channel");
 | 
				
			||||||
 | 
					    return INT_MAX;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if(0 == prec)
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  assert(x < loader->GetWidth());
 | 
				
			||||||
 | 
					  assert(y < loader->GetHeight());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int pixelIdx = y * loader->GetWidth() + x;
 | 
				
			||||||
 | 
					  const unsigned int val = data[pixelIdx];
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  if(prec < 8) {
 | 
				
			||||||
 | 
					    unsigned int ret = 0;
 | 
				
			||||||
 | 
					    for(unsigned int precLeft = 8; precLeft > 0; precLeft -= min(prec, abs(prec - precLeft))) {
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      if(prec > precLeft) {
 | 
				
			||||||
 | 
						const int toShift = prec - precLeft;
 | 
				
			||||||
 | 
						ret = ret << precLeft;
 | 
				
			||||||
 | 
						ret |= val >> toShift;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      else {
 | 
				
			||||||
 | 
						ret = ret << prec;
 | 
				
			||||||
 | 
						ret |= val;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else if(prec > 8) {
 | 
				
			||||||
 | 
					    const int toShift = prec - 8;
 | 
				
			||||||
 | 
					    return val >> toShift;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//////////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// ImageFile implementation
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//////////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ImageFile::ImageFile(const char *filename) : 
 | 
					ImageFile::ImageFile(const char *filename) : 
 | 
				
			||||||
  m_PixelData(0),
 | 
					  m_PixelData(0),
 | 
				
			||||||
  m_FileFormat(  DetectFileFormat(filename) )
 | 
					  m_FileFormat(  DetectFileFormat(filename) )
 | 
				
			||||||
| 
						 | 
					@ -80,7 +176,77 @@ bool ImageFile::LoadImage(const unsigned char *rawImageData) {
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return false;
 | 
					  m_Width = loader->GetWidth();
 | 
				
			||||||
 | 
					  m_Height = loader->GetHeight();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Create RGBA buffer 
 | 
				
			||||||
 | 
					  const unsigned int dataSz = 4 * m_Width * m_Height;
 | 
				
			||||||
 | 
					  m_PixelData = new unsigned char[dataSz];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Populate buffer in block stream order... make 
 | 
				
			||||||
 | 
					  // sure that width and height are aligned to multiples of four.
 | 
				
			||||||
 | 
					  const unsigned int aw = ((m_Width + 3) >> 2) << 2;
 | 
				
			||||||
 | 
					  const unsigned int ah = ((m_Height + 3) >> 2) << 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int byteIdx = 0;
 | 
				
			||||||
 | 
					  for(int i = 0; i < ah; i+=4) {
 | 
				
			||||||
 | 
					    for(int j = 0; j < aw; j+= 4) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // For each block, visit the pixels in sequential order
 | 
				
			||||||
 | 
					      for(int y = i; y < i+4; y++) {
 | 
				
			||||||
 | 
						for(int x = j; x < j+4; x++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  if(y >= m_Height || x >= m_Width) {
 | 
				
			||||||
 | 
						    m_PixelData[byteIdx++] = 0; // r
 | 
				
			||||||
 | 
						    m_PixelData[byteIdx++] = 0; // g
 | 
				
			||||||
 | 
						    m_PixelData[byteIdx++] = 0; // b
 | 
				
			||||||
 | 
						    m_PixelData[byteIdx++] = 0; // a
 | 
				
			||||||
 | 
						    continue;
 | 
				
			||||||
 | 
						  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  unsigned int redVal = GetChannelForPixel(loader, x, y, 0);
 | 
				
			||||||
 | 
						  if(redVal == INT_MAX)
 | 
				
			||||||
 | 
						    return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  unsigned int greenVal = redVal;
 | 
				
			||||||
 | 
						  unsigned int blueVal = redVal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  if(loader->GetGreenChannelPrecision() > 0) {
 | 
				
			||||||
 | 
						    greenVal = GetChannelForPixel(loader, x, y, 1);
 | 
				
			||||||
 | 
						    if(greenVal == INT_MAX)
 | 
				
			||||||
 | 
						      return false;
 | 
				
			||||||
 | 
						  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  if(loader->GetBlueChannelPrecision() > 0) {
 | 
				
			||||||
 | 
						    blueVal = GetChannelForPixel(loader, x, y, 2);
 | 
				
			||||||
 | 
						    if(blueVal == INT_MAX)
 | 
				
			||||||
 | 
						      return false;
 | 
				
			||||||
 | 
						  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  unsigned int alphaVal = 0xFF;
 | 
				
			||||||
 | 
						  if(loader->GetAlphaChannelPrecision() > 0) {
 | 
				
			||||||
 | 
						    alphaVal = GetChannelForPixel(loader, x, y, 3);
 | 
				
			||||||
 | 
						    if(alphaVal == INT_MAX)
 | 
				
			||||||
 | 
						      return false;
 | 
				
			||||||
 | 
						  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  // Red channel
 | 
				
			||||||
 | 
						  m_PixelData[byteIdx++] = redVal & 0xFF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  // Green channel
 | 
				
			||||||
 | 
						  m_PixelData[byteIdx++] = greenVal & 0xFF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  // Blue channel
 | 
				
			||||||
 | 
						  m_PixelData[byteIdx++] = blueVal & 0xFF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  // Alpha channel
 | 
				
			||||||
 | 
						  m_PixelData[byteIdx++] = alphaVal & 0xFF;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef _MSC_VER
 | 
					#ifdef _MSC_VER
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue