281 lines
9.0 KiB
C++
281 lines
9.0 KiB
C++
// File: crn_pixel_format.cpp
|
|
// See Copyright Notice and license at the end of inc/crnlib.h
|
|
#include "crn_core.h"
|
|
#include "crn_pixel_format.h"
|
|
#include "crn_image.h"
|
|
|
|
namespace crnlib
|
|
{
|
|
namespace pixel_format_helpers
|
|
{
|
|
const pixel_format g_all_pixel_formats[] =
|
|
{
|
|
PIXEL_FMT_DXT1,
|
|
PIXEL_FMT_DXT2,
|
|
PIXEL_FMT_DXT3,
|
|
PIXEL_FMT_DXT4,
|
|
PIXEL_FMT_DXT5,
|
|
PIXEL_FMT_3DC,
|
|
PIXEL_FMT_DXN,
|
|
PIXEL_FMT_DXT5A,
|
|
PIXEL_FMT_DXT5_CCxY,
|
|
PIXEL_FMT_DXT5_xGxR,
|
|
PIXEL_FMT_DXT5_xGBR,
|
|
PIXEL_FMT_DXT5_AGBR,
|
|
PIXEL_FMT_DXT1A,
|
|
PIXEL_FMT_ETC1,
|
|
PIXEL_FMT_R8G8B8,
|
|
PIXEL_FMT_L8,
|
|
PIXEL_FMT_A8,
|
|
PIXEL_FMT_A8L8,
|
|
PIXEL_FMT_A8R8G8B8
|
|
};
|
|
|
|
uint get_num_formats()
|
|
{
|
|
return sizeof(g_all_pixel_formats) / sizeof(g_all_pixel_formats[0]);
|
|
}
|
|
|
|
pixel_format get_pixel_format_by_index(uint index)
|
|
{
|
|
CRNLIB_ASSERT(index < get_num_formats());
|
|
return g_all_pixel_formats[index];
|
|
}
|
|
|
|
const char* get_pixel_format_string(pixel_format fmt)
|
|
{
|
|
switch (fmt)
|
|
{
|
|
case PIXEL_FMT_INVALID: return "INVALID";
|
|
case PIXEL_FMT_DXT1: return "DXT1";
|
|
case PIXEL_FMT_DXT1A: return "DXT1A";
|
|
case PIXEL_FMT_DXT2: return "DXT2";
|
|
case PIXEL_FMT_DXT3: return "DXT3";
|
|
case PIXEL_FMT_DXT4: return "DXT4";
|
|
case PIXEL_FMT_DXT5: return "DXT5";
|
|
case PIXEL_FMT_3DC: return "3DC";
|
|
case PIXEL_FMT_DXN: return "DXN";
|
|
case PIXEL_FMT_DXT5A: return "DXT5A";
|
|
case PIXEL_FMT_DXT5_CCxY: return "DXT5_CCxY";
|
|
case PIXEL_FMT_DXT5_xGxR: return "DXT5_xGxR";
|
|
case PIXEL_FMT_DXT5_xGBR: return "DXT5_xGBR";
|
|
case PIXEL_FMT_DXT5_AGBR: return "DXT5_AGBR";
|
|
case PIXEL_FMT_ETC1: return "ETC1";
|
|
case PIXEL_FMT_R8G8B8: return "R8G8B8";
|
|
case PIXEL_FMT_A8R8G8B8: return "A8R8G8B8";
|
|
case PIXEL_FMT_A8: return "A8";
|
|
case PIXEL_FMT_L8: return "L8";
|
|
case PIXEL_FMT_A8L8: return "A8L8";
|
|
default: break;
|
|
}
|
|
CRNLIB_ASSERT(false);
|
|
return "?";
|
|
}
|
|
|
|
const char* get_crn_format_string(crn_format fmt)
|
|
{
|
|
switch (fmt)
|
|
{
|
|
case cCRNFmtDXT1: return "DXT1";
|
|
case cCRNFmtDXT3: return "DXT3";
|
|
case cCRNFmtDXT5: return "DXT5";
|
|
case cCRNFmtDXT5_CCxY: return "DXT5_CCxY";
|
|
case cCRNFmtDXT5_xGBR: return "DXT5_xGBR";
|
|
case cCRNFmtDXT5_AGBR: return "DXT5_AGBR";
|
|
case cCRNFmtDXT5_xGxR: return "DXT5_xGxR";
|
|
case cCRNFmtDXN_XY: return "DXN_XY";
|
|
case cCRNFmtDXN_YX: return "DXN_YX";
|
|
case cCRNFmtDXT5A: return "DXT5A";
|
|
case cCRNFmtETC1: return "ETC1";
|
|
default: break;
|
|
}
|
|
CRNLIB_ASSERT(false);
|
|
return "?";
|
|
}
|
|
|
|
component_flags get_component_flags(pixel_format fmt)
|
|
{
|
|
// These flags are for *uncooked* pixels, i.e. after after adding Z to DXN maps, or converting YCC maps to RGB, etc.
|
|
|
|
uint flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagAValid | cCompFlagGrayscale;
|
|
switch (fmt)
|
|
{
|
|
case PIXEL_FMT_DXT1:
|
|
case PIXEL_FMT_ETC1:
|
|
{
|
|
flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid;
|
|
break;
|
|
}
|
|
case PIXEL_FMT_DXT1A:
|
|
{
|
|
flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagAValid;
|
|
break;
|
|
}
|
|
case PIXEL_FMT_DXT2:
|
|
case PIXEL_FMT_DXT3:
|
|
{
|
|
flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagAValid;
|
|
break;
|
|
}
|
|
case PIXEL_FMT_DXT4:
|
|
case PIXEL_FMT_DXT5:
|
|
{
|
|
flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagAValid;
|
|
break;
|
|
}
|
|
case PIXEL_FMT_DXT5A:
|
|
{
|
|
flags = cCompFlagAValid;
|
|
break;
|
|
}
|
|
case PIXEL_FMT_DXT5_CCxY:
|
|
{
|
|
flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagLumaChroma;
|
|
break;
|
|
}
|
|
case PIXEL_FMT_DXT5_xGBR:
|
|
{
|
|
flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagNormalMap;
|
|
break;
|
|
}
|
|
case PIXEL_FMT_DXT5_AGBR:
|
|
{
|
|
flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagAValid | cCompFlagNormalMap;
|
|
break;
|
|
}
|
|
case PIXEL_FMT_DXT5_xGxR:
|
|
{
|
|
flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagNormalMap;
|
|
break;
|
|
}
|
|
case PIXEL_FMT_3DC:
|
|
{
|
|
flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagNormalMap;
|
|
break;
|
|
}
|
|
case PIXEL_FMT_DXN:
|
|
{
|
|
flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagNormalMap;
|
|
break;
|
|
}
|
|
case PIXEL_FMT_R8G8B8:
|
|
{
|
|
flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid;
|
|
break;
|
|
}
|
|
case PIXEL_FMT_A8R8G8B8:
|
|
{
|
|
flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagAValid;
|
|
break;
|
|
}
|
|
case PIXEL_FMT_A8:
|
|
{
|
|
flags = cCompFlagAValid;
|
|
break;
|
|
}
|
|
case PIXEL_FMT_L8:
|
|
{
|
|
flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagGrayscale;
|
|
break;
|
|
}
|
|
case PIXEL_FMT_A8L8:
|
|
{
|
|
flags = cCompFlagRValid | cCompFlagGValid | cCompFlagBValid | cCompFlagAValid | cCompFlagGrayscale;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
CRNLIB_ASSERT(0);
|
|
break;
|
|
}
|
|
}
|
|
return static_cast<component_flags>(flags);
|
|
}
|
|
|
|
crn_format convert_pixel_format_to_best_crn_format(pixel_format crn_fmt)
|
|
{
|
|
crn_format fmt = cCRNFmtDXT1;
|
|
switch (crn_fmt)
|
|
{
|
|
case PIXEL_FMT_DXT1:
|
|
case PIXEL_FMT_DXT1A:
|
|
fmt = cCRNFmtDXT1;
|
|
break;
|
|
case PIXEL_FMT_DXT2:
|
|
case PIXEL_FMT_DXT3:
|
|
case PIXEL_FMT_DXT4:
|
|
case PIXEL_FMT_DXT5:
|
|
fmt = cCRNFmtDXT5;
|
|
break;
|
|
case PIXEL_FMT_3DC:
|
|
fmt = cCRNFmtDXN_YX;
|
|
break;
|
|
case PIXEL_FMT_DXN:
|
|
fmt = cCRNFmtDXN_XY;
|
|
break;
|
|
case PIXEL_FMT_DXT5A:
|
|
fmt = cCRNFmtDXT5A;
|
|
break;
|
|
case PIXEL_FMT_R8G8B8:
|
|
case PIXEL_FMT_L8:
|
|
fmt = cCRNFmtDXT1;
|
|
break;
|
|
case PIXEL_FMT_A8R8G8B8:
|
|
case PIXEL_FMT_A8:
|
|
case PIXEL_FMT_A8L8:
|
|
fmt = cCRNFmtDXT5;
|
|
break;
|
|
case PIXEL_FMT_DXT5_CCxY:
|
|
fmt = cCRNFmtDXT5_CCxY;
|
|
break;
|
|
case PIXEL_FMT_DXT5_xGBR:
|
|
fmt = cCRNFmtDXT5_xGBR;
|
|
break;
|
|
case PIXEL_FMT_DXT5_AGBR:
|
|
fmt = cCRNFmtDXT5_AGBR;
|
|
break;
|
|
case PIXEL_FMT_DXT5_xGxR:
|
|
fmt = cCRNFmtDXT5_xGxR;
|
|
break;
|
|
case PIXEL_FMT_ETC1:
|
|
fmt = cCRNFmtETC1;
|
|
break;
|
|
default:
|
|
{
|
|
CRNLIB_ASSERT(false);
|
|
break;
|
|
}
|
|
}
|
|
return fmt;
|
|
}
|
|
|
|
pixel_format convert_crn_format_to_pixel_format(crn_format fmt)
|
|
{
|
|
switch (fmt)
|
|
{
|
|
case cCRNFmtDXT1: return PIXEL_FMT_DXT1;
|
|
case cCRNFmtDXT3: return PIXEL_FMT_DXT3;
|
|
case cCRNFmtDXT5: return PIXEL_FMT_DXT5;
|
|
case cCRNFmtDXT5_CCxY: return PIXEL_FMT_DXT5_CCxY;
|
|
case cCRNFmtDXT5_xGxR: return PIXEL_FMT_DXT5_xGxR;
|
|
case cCRNFmtDXT5_xGBR: return PIXEL_FMT_DXT5_xGBR;
|
|
case cCRNFmtDXT5_AGBR: return PIXEL_FMT_DXT5_AGBR;
|
|
case cCRNFmtDXN_XY: return PIXEL_FMT_DXN;
|
|
case cCRNFmtDXN_YX: return PIXEL_FMT_3DC;
|
|
case cCRNFmtDXT5A: return PIXEL_FMT_DXT5A;
|
|
case cCRNFmtETC1: return PIXEL_FMT_ETC1;
|
|
default:
|
|
{
|
|
CRNLIB_ASSERT(false);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return PIXEL_FMT_INVALID;
|
|
}
|
|
|
|
} // namespace pixel_format
|
|
|
|
} // namespace crnlib
|
|
|