00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <fs/ras/fsTgaLdr.h>
00015
00016
00017 #if defined(FS_HAS_FSASSERT)
00018 # include <fs/sys/fsAssert.h>
00019 #else
00020 # include <cassert>
00021 # if !defined(FS_ASSERT)
00022 # define FS_ASSERT(exp) assert(exp)
00023 # endif
00024 # if !defined(FS_ASSERT_MSG)
00025 # define FS_ASSERT_MSG(exp, msg) assert(exp && msg)
00026 # endif
00027 # if !defined(FS_VERIFY)
00028 # define FS_VERIFY(exp) \
00029 { bool bExp = !!(exp); assert(bExp && #exp); bExp; }
00030 # endif
00031 # if !defined(FS_VERIFY_MSG)
00032 # define FS_VERIFY_MSG(exp, msg) \
00033 { bool bExp = !!(exp); assert(bExp && #exp && msg); bExp; }
00034 # endif
00035 # if !defined(FS_STATIC_ASSERT)
00036 # define FS_STATIC_ASSERT(exp) { char error[(exp) ? 1 : 0]; error; }
00037 # endif
00038 #endif
00039 #if !defined(FS_VERIFY_RETURN)
00040 # define FS_VERIFY_RETURN(exp) \
00041 if(!(exp)) { FS_ASSERT_MSG(0, #exp "<return>"); return; }
00042 #endif
00043 #if !defined(FS_VERIFY_RETURN_VAL)
00044 # define FS_VERIFY_RETURN_VAL(exp, ret) \
00045 if(!(exp)) { FS_ASSERT_MSG(0, #exp "<returns:>" #ret); return (ret); }
00046 #endif
00047
00048
00049 #include <stdio.h>
00050 #include <vector>
00051
00052
00053 #if defined(FS_HAS_FSMEMMGR)
00054 # include <fs/sys/fsMemMgr.h>
00055 #endif
00056
00057 #if (_MSC_VER >= 1400) // MSVC8
00058 # pragma warning(disable : 4996) // function was marked as deprecated
00059 #endif
00060
00061 using namespace fs::ras;
00062
00063
00064
00065 namespace {
00066
00067 template<typename T>
00068 bool ReadType(T &Dest, FILE *pIn)
00069 {
00070 return ::fread(&Dest, sizeof(T), 1, pIn) == 1;
00071 }
00072
00073 struct TgaHdr_t
00074 {
00075 typedef unsigned char uint8;
00076 typedef unsigned short uint16;
00077
00078 uint8 m_uTagLen;
00079 uint8 m_uNoPal;
00080 uint8 m_uImgFmt;
00081 uint16 m_uPalStart;
00082 uint16 m_uPalLen;
00083 uint8 m_uPalBits;
00084 uint16 m_uXoff;
00085 uint16 m_uYoff;
00086 uint16 m_uW;
00087 uint16 m_uH;
00088 uint8 m_uPxBits;
00089 uint8 m_uImgDsc;
00090
00091 bool Read(FILE *pIn)
00092 {
00093 FS_STATIC_ASSERT(sizeof(uint8) == 1);
00094 FS_STATIC_ASSERT(sizeof(uint16) == 2);
00095
00096 if(!ReadType(m_uTagLen, pIn)) return false;
00097 if(!ReadType(m_uNoPal, pIn)) return false;
00098 if(!ReadType(m_uImgFmt, pIn)) return false;
00099 if(!ReadType(m_uPalStart, pIn)) return false;
00100 if(!ReadType(m_uPalLen, pIn)) return false;
00101 if(!ReadType(m_uPalBits, pIn)) return false;
00102 if(!ReadType(m_uXoff, pIn)) return false;
00103 if(!ReadType(m_uYoff, pIn)) return false;
00104 if(!ReadType(m_uW, pIn)) return false;
00105 if(!ReadType(m_uH, pIn)) return false;
00106 if(!ReadType(m_uPxBits, pIn)) return false;
00107 if(!ReadType(m_uImgDsc, pIn)) return false;
00108
00109 return true;
00110 }
00111 };
00112
00113
00114
00115 class TgaLdrImpl_t
00116 {
00117 public:
00118
00119 explicit TgaLdrImpl_t(const char *pszFile);
00120 bool IsValid() const;
00121
00122 int GetW() const;
00123 int GetH() const;
00124 const TgaLdr_t::PxFmt888_t * GetData888() const;
00125 const TgaLdr_t::PxFmt8888_t * GetData8888() const;
00126
00127 private:
00128
00129 TgaLdrImpl_t();
00130 TgaLdrImpl_t(const TgaLdrImpl_t &);
00131 TgaLdrImpl_t & operator = (const TgaLdrImpl_t &);
00132
00133
00134
00135 int m_nW, m_nH;
00136 int m_nPxBits;
00137 typedef std::vector<TgaHdr_t::uint8> Data_t;
00138 Data_t m_Data;
00139 };
00140
00141 TgaLdrImpl_t::TgaLdrImpl_t(const char *pszFile):
00142 m_nW(0),
00143 m_nH(0),
00144 m_nPxBits(0)
00145 {
00146 FS_VERIFY_RETURN(pszFile);
00147
00148
00149
00150
00151 FILE *pIn = ::fopen(pszFile, "rb");
00152 if(!pIn)
00153 return;
00154
00155
00156 TgaHdr_t Hdr;
00157 if(!Hdr.Read(pIn))
00158 {
00159 ::fclose(pIn);
00160 return;
00161 }
00162
00163
00164 if(Hdr.m_uImgFmt != 2)
00165 {
00166 ::fclose(pIn);
00167 return;
00168 }
00169
00170
00171 if(Hdr.m_uPxBits != 24 && Hdr.m_uPxBits != 32)
00172 {
00173 ::fclose(pIn);
00174 return;
00175 }
00176
00177
00178 size_t uDataSize = Hdr.m_uW * Hdr.m_uH * Hdr.m_uPxBits / 8;
00179 Data_t Data;
00180 Data.resize(uDataSize);
00181
00182 if(::fread(&Data[0], uDataSize, 1, pIn) != 1)
00183 {
00184 ::fclose(pIn);
00185 return;
00186 }
00187
00188
00189 ::fclose(pIn);
00190
00191
00192
00193 if(Hdr.m_uPxBits == 24)
00194 {
00195
00196 for(size_t i = 0, n = Hdr.m_uW * Hdr.m_uH * 3; i < n; i += 3)
00197 {
00198 TgaHdr_t::uint8 tmp = Data[i];
00199 Data[i] = Data[i + 2];
00200 Data[i + 2] = tmp;
00201 }
00202 }
00203 else if(Hdr.m_uPxBits == 32)
00204 {
00205
00206 for(size_t i = 0, n = Hdr.m_uW * Hdr.m_uH * 4; i < n; i += 4)
00207 {
00208 TgaHdr_t::uint8 tmp = Data[i];
00209 Data[i] = Data[i + 2];
00210 Data[i + 2] = tmp;
00211 }
00212 }
00213
00214 if((Hdr.m_uImgDsc & 1 << 5) == 0)
00215 {
00216
00217 const int uPxBytes = Hdr.m_uPxBits / 8;
00218 for(int y = 0, yn = Hdr.m_uH / 2; y < yn; ++y)
00219 {
00220 TgaHdr_t::uint8 *pSrc1 = &Data[0] + Hdr.m_uW * uPxBytes * y;
00221 TgaHdr_t::uint8 *pSrc2 = &Data[0] + Hdr.m_uW * uPxBytes *
00222 (Hdr.m_uH - y - 1);
00223
00224 for(int x = 0, xn = Hdr.m_uW * uPxBytes; x < xn; ++x)
00225 {
00226 TgaHdr_t::uint8 tmp = *pSrc1;
00227 *pSrc1 = *pSrc2;
00228 *pSrc2 = tmp;
00229 ++pSrc1;
00230 ++pSrc2;
00231 }
00232 }
00233 }
00234
00235
00236
00237 m_nW = Hdr.m_uW;
00238 m_nH = Hdr.m_uH;
00239 m_nPxBits = Hdr.m_uPxBits;
00240 m_Data.swap(Data);
00241 }
00242
00243 bool TgaLdrImpl_t::IsValid() const
00244 {
00245 return !m_Data.empty();
00246 }
00247
00248 int TgaLdrImpl_t::GetW() const
00249 {
00250 FS_VERIFY_RETURN_VAL(IsValid(), 0);
00251 return m_nW;
00252 }
00253
00254 int TgaLdrImpl_t::GetH() const
00255 {
00256 FS_VERIFY_RETURN_VAL(IsValid(), 0);
00257 return m_nH;
00258 }
00259
00260 const TgaLdr_t::PxFmt888_t * TgaLdrImpl_t::GetData888() const
00261 {
00262 FS_VERIFY_RETURN_VAL(IsValid(), 0);
00263 FS_STATIC_ASSERT(sizeof(TgaLdr_t::PxFmt888_t) == 3);
00264
00265 return m_nPxBits == 24 ?
00266 reinterpret_cast<const TgaLdr_t::PxFmt888_t *>(&m_Data[0]) : 0;
00267 }
00268
00269 const TgaLdr_t::PxFmt8888_t * TgaLdrImpl_t::GetData8888() const
00270 {
00271 FS_VERIFY_RETURN_VAL(IsValid(), 0);
00272 FS_STATIC_ASSERT(sizeof(TgaLdr_t::PxFmt8888_t) == 4);
00273
00274 return m_nPxBits == 32 ?
00275 reinterpret_cast<const TgaLdr_t::PxFmt8888_t *>(&m_Data[0]) : 0;
00276 }
00277
00278 }
00279
00280
00281
00282 TgaLdr_t::TgaLdr_t(const char *pszFile):
00283 m_pImpl(new TgaLdrImpl_t(pszFile))
00284 {
00285 FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00286 }
00287
00288 TgaLdr_t::~TgaLdr_t()
00289 {
00290 FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00291 delete static_cast<TgaLdrImpl_t *>(m_pImpl);
00292 }
00293
00294 bool TgaLdr_t::IsValid() const
00295 {
00296 FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00297 return static_cast<TgaLdrImpl_t *>(m_pImpl)->IsValid();
00298 }
00299
00300 int TgaLdr_t::GetW() const
00301 {
00302 FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00303 return static_cast<TgaLdrImpl_t *>(m_pImpl)->GetW();
00304 }
00305
00306 int TgaLdr_t::GetH() const
00307 {
00308 FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00309 return static_cast<TgaLdrImpl_t *>(m_pImpl)->GetH();
00310 }
00311
00312 const TgaLdr_t::PxFmt888_t * TgaLdr_t::GetData888() const
00313 {
00314 FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00315 return static_cast<TgaLdrImpl_t *>(m_pImpl)->GetData888();
00316 }
00317
00318 const TgaLdr_t::PxFmt8888_t * TgaLdr_t::GetData8888() const
00319 {
00320 FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00321 return static_cast<TgaLdrImpl_t *>(m_pImpl)->GetData8888();
00322 }
00323