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 |   |
20 | namespace 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 |   |
54 | bool tImage::tIsNormalFormat(tPixelFormat format)  |
55 | {  |
56 | if ((format >= tPixelFormat::FirstNormal) && (format <= tPixelFormat::LastNormal))  |
57 | return true;  |
58 |   |
59 | return false;  |
60 | }  |
61 |   |
62 |   |
63 | bool tImage::tIsBlockFormat(tPixelFormat format)  |
64 | {  |
65 | if ((format >= tPixelFormat::FirstBlock) && (format <= tPixelFormat::LastBlock))  |
66 | return true;  |
67 |   |
68 | return false;  |
69 | }  |
70 |   |
71 |   |
72 | bool tImage::tIsHDRFormat(tPixelFormat format)  |
73 | {  |
74 | if ((format >= tPixelFormat::FirstHDR) && (format <= tPixelFormat::LastHDR))  |
75 | return true;  |
76 |   |
77 | return false;  |
78 | }  |
79 |   |
80 |   |
81 | bool tImage::tIsPaletteFormat(tPixelFormat format)  |
82 | {  |
83 | if ((format >= tPixelFormat::FirstPAL) && (format <= tPixelFormat::LastPAL))  |
84 | return true;  |
85 |   |
86 | return false;  |
87 | }  |
88 |   |
89 |   |
90 | int 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 |   |
115 | int 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 |   |
126 | const 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 | |