1// tPixelFormat.cpp 
2// 
3// Pixel formats in Tacent. Not all formats are fully supported. Certainly BC 4, 5, and 7 may not have extensive HW 
4// support at this time. 
5// 
6// Copyright (c) 2004-2006, 2017, 2019 Tristan Grimmer. 
7// Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby 
8// granted, provided that the above copyright notice and this permission notice appear in all copies. 
9// 
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 
11// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 
12// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
13// AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 
14// PERFORMANCE OF THIS SOFTWARE. 
15 
16#include <Foundation/tAssert.h> 
17#include "Image/tPixelFormat.h" 
18 
19 
20namespace tImage 
21{ 
22 int NormalFormat_BytesPerPixel[int(tPixelFormat::NumNormalFormats)] = 
23 { 
24 3, // R8G8B8 
25 4, // R8G8B8A8 
26 3, // B8G8R8 
27 4, // B8G8R8A8 
28 2, // G3B5A1R5G2 
29 2, // G4B4A4R4 
30 2, // G3B5R5G3 
31 2 // L8A8 
32 }; 
33 
34 int BlockFormat_BytesPer4x4PixelBlock[int(tPixelFormat::NumBlockFormats)] = 
35 { 
36 8, // BC1_DXT1 
37 8, // BC1_DXT1BA 
38 16, // BC2_DXT3 
39 16, // BC3_DXT5 
40 8, // BC4_ATI1 
41 16, // BC5_ATI2 
42 16, // BC6H 
43 16, // BC7 
44 }; 
45 
46 int HDRFormat_BytesPerPixel[int(tPixelFormat::NumHDRFormats)] = 
47 { 
48 4, // RAD. 3 bytes for each RGB. 1 byte shared exponent. 
49 0 // EXR. @todo There are multiple exr pixel formats. We don't yet determine which one. 
50 }; 
51} 
52 
53 
54bool tImage::tIsNormalFormat(tPixelFormat format) 
55{ 
56 if ((format >= tPixelFormat::FirstNormal) && (format <= tPixelFormat::LastNormal)) 
57 return true; 
58 
59 return false; 
60} 
61 
62 
63bool tImage::tIsBlockFormat(tPixelFormat format) 
64{ 
65 if ((format >= tPixelFormat::FirstBlock) && (format <= tPixelFormat::LastBlock)) 
66 return true; 
67 
68 return false; 
69} 
70 
71 
72bool tImage::tIsHDRFormat(tPixelFormat format) 
73{ 
74 if ((format >= tPixelFormat::FirstHDR) && (format <= tPixelFormat::LastHDR)) 
75 return true; 
76 
77 return false; 
78} 
79 
80 
81bool tImage::tIsPaletteFormat(tPixelFormat format) 
82{ 
83 if ((format >= tPixelFormat::FirstPAL) && (format <= tPixelFormat::LastPAL)) 
84 return true; 
85 
86 return false; 
87} 
88 
89 
90int tImage::tGetBitsPerPixel(tPixelFormat format) 
91{ 
92 if (tIsNormalFormat(format)) 
93 return 8*NormalFormat_BytesPerPixel[int(format) - int(tPixelFormat::FirstNormal)]; 
94 
95 if (tIsBlockFormat(format)) 
96 return (8*tGetBytesPer4x4PixelBlock(format)) >> 4; 
97 
98 if (tIsHDRFormat(format)) 
99 return 8*HDRFormat_BytesPerPixel[int(format) - int(tPixelFormat::FirstHDR)]; 
100 
101 if (tIsPaletteFormat(format)) 
102 { 
103 switch (format) 
104 { 
105 case tPixelFormat::PAL_8BIT: return 8; 
106 case tPixelFormat::PAL_4BIT: return 4; 
107 case tPixelFormat::PAL_1BIT: return 1; 
108 } 
109 } 
110 
111 return -1; 
112} 
113 
114 
115int tImage::tGetBytesPer4x4PixelBlock(tPixelFormat format) 
116{ 
117 if (format == tPixelFormat::Invalid) 
118 return -1; 
119 
120 tAssert(tIsBlockFormat(format)); 
121 int index = int(format) - int(tPixelFormat::FirstBlock); 
122 return BlockFormat_BytesPer4x4PixelBlock[index]; 
123} 
124 
125 
126const char* tImage::tGetPixelFormatName(tPixelFormat pixelFormat) 
127{ 
128 const char* names[] = 
129 { 
130 "Unknown", 
131 "R8G8B8", 
132 "R8G8B8A8", 
133 "B8G8R8", 
134 "B8G8R8A8", 
135 "G3B5A1R5G2", 
136 "G4B4A4R4", 
137 "G3B5R5G3", 
138 "L8A8", 
139 "R32F", 
140 "G32R32F", 
141 "A32B32G32R32F", 
142 "BC1_DXT1", 
143 "BC1_DXT1BA", 
144 "BC2_DXT3", 
145 "BC3_DXT5", 
146 "BC4_ATI1", 
147 "BC5_ATI2", 
148 "BC6H", 
149 "BC7", 
150 "RADIANCE", 
151 "EXR", 
152 "PAL8BIT", 
153 "PAL4BIT", 
154 "PAL1BIT" 
155 }; 
156 
157 tStaticAssert(int(tPixelFormat::NumPixelFormats)+1 == sizeof(names)/sizeof(*names)); 
158 int index = int(pixelFormat) + 1; 
159 return names[index]; 
160} 
161