1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     tpl_ReadTexturePackage.cpp
4 
5   Copyright (C)2009 Nintendo Co., Ltd.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Rev: 27744 $
14  *---------------------------------------------------------------------------*/
15 
16 #include <nn/util.h>
17 #include <nn/tpl.h>
18 
19 #include <cstring>
20 #include <cstdio>
21 
22 #include "tpl_crc32.h"
23 #include "tpl_Internal.h"
24 
25 namespace nn { namespace tpl { namespace CTR {
26 
27 // テクスチャパッケージファイルに含まれるテクスチャ数を取得します。
GetTextureNum(const void * pTexPackage)28 u16 GetTextureNum(const void* pTexPackage)
29 {
30     if (!pTexPackage)
31     {
32         NN_TASSERT_(pTexPackage != 0);
33         return 0;
34     }
35     const CtrTexturePackageHeader* header =
36         reinterpret_cast<const CtrTexturePackageHeader*>(pTexPackage);
37     return header->numTexture;
38 }
39 
40 // テクスチャインデックス取得関数
GetTextureIndex(const void * pTexPackage,const char * texPath)41 s16 GetTextureIndex(const void* pTexPackage, const char* texPath)
42 {
43     if(!pTexPackage || !texPath)
44     {
45         NN_TASSERT_((pTexPackage != 0) && (texPath != 0));
46         return -1;
47     }
48     // CRC32のハッシュコードを作成。
49     int fileNameLen = (int)::std::strlen(texPath);
50     unsigned int crc32key = calculate_crc32(texPath, fileNameLen);
51 
52     const CtrTexturePackageHeader &header =
53         *reinterpret_cast<const CtrTexturePackageHeader *>(pTexPackage);
54     const CtrTextureHash *texHash = reinterpret_cast<const CtrTextureHash *>
55                       ((const char*)pTexPackage + (header.texHashOffset));
56 
57     // パッケージ内のテクスチャ情報と比較して一致するものを探す。
58     TPK_SEARCH_DATA data = { texPath, fileNameLen, pTexPackage };
59     int t = search_crc32_data(
60         texHash, header.numTexture, sizeof(CtrTextureHash), crc32key, &data);
61 
62     if(t < 0) return -1;
63     return texHash[t].index;
64 }
65 
66 // テクスチャ取得関数
GetTexture(s32 * mipLevel,u32 * mipmapSize,const void * pTexPackage,const s16 texIndex)67 void* GetTexture(s32* mipLevel, u32* mipmapSize, const void* pTexPackage, const s16 texIndex)
68 {
69     if(!pTexPackage)
70     {
71         NN_TASSERT_(pTexPackage != 0);
72         return 0;
73     }
74 
75     // 指定された番号がテクスチャの枚数に収まっているか確認。
76     const CtrTexturePackageHeader *header =
77         reinterpret_cast<const CtrTexturePackageHeader *>(pTexPackage);
78     NN_TASSERT_((0 <= texIndex) && (texIndex < header->numTexture));
79     if((texIndex < 0) || (header->numTexture <= texIndex))
80     {
81         return 0;
82     }
83 
84     const CtrTextureInfo *texInfo = reinterpret_cast<const CtrTextureInfo *>
85         (((const char*)pTexPackage) + (sizeof(CtrTexturePackageHeader)) + (sizeof(CtrTextureInfo) * texIndex));
86 
87     if(!texInfo)
88     {
89         return 0;
90     }
91 
92     // get texture size.
93     const unsigned int *Size = reinterpret_cast<const unsigned int *>
94         (((const char*)pTexPackage) + (4 * texInfo->bitmapSizeOffset));
95 
96     *mipLevel = static_cast<int>(texInfo->mipLevel);
97     for(int i=0; i < *mipLevel; i++)
98     {
99         mipmapSize[i] = Size[i];
100     }
101 
102     return (void*)(((const char*)pTexPackage) + (header->texDataOffset + texInfo->texDataOffset));
103 }
104 
105 // テクスチャ情報取得関数
GetTextureInfo(CtrTextureInfo * pTexInfo,const void * pTexPackage,const s16 texIndex)106 bool GetTextureInfo(CtrTextureInfo* pTexInfo, const void* pTexPackage, const s16 texIndex)
107 {
108     if(!pTexPackage || !pTexInfo)
109     {
110         NN_TASSERT_((pTexPackage != 0) && (pTexInfo != 0));
111         return false;
112     }
113 
114 
115     // 指定された番号がテクスチャの枚数に収まっているか確認。
116     const CtrTexturePackageHeader *header =
117         reinterpret_cast<const CtrTexturePackageHeader *>(pTexPackage);
118     NN_TASSERT_((0 <= texIndex) && (texIndex < header->numTexture));
119     if((texIndex < 0) || (header->numTexture <= texIndex))
120     {
121         return false;
122     }
123 
124     const CtrTextureInfo *texInfo = reinterpret_cast<const CtrTextureInfo *>
125         (((const char*)pTexPackage) + (sizeof(CtrTexturePackageHeader)) + (sizeof(CtrTextureInfo) * texIndex));
126 
127     pTexInfo->filePathOffset   = texInfo->filePathOffset;
128     pTexInfo->texDataSize      = texInfo->texDataSize;
129     pTexInfo->texDataOffset    = texInfo->texDataOffset;
130     pTexInfo->texFormat        = texInfo->texFormat;
131     pTexInfo->width            = texInfo->width;
132     pTexInfo->height           = texInfo->height;
133     pTexInfo->mipLevel         = texInfo->mipLevel;
134     pTexInfo->type             = texInfo->type;
135     pTexInfo->cubeDir          = texInfo->cubeDir;
136     pTexInfo->bitmapSizeOffset = texInfo->bitmapSizeOffset;
137     pTexInfo->srcFileTime      = texInfo->srcFileTime;
138 
139     return true;
140 }
141 
142 
143 // テクスチャパッケージヘッダーチェック関数(ヘルパー関数)
CheckTexturePackageHeader(const void * pTexPackage)144 bool CheckTexturePackageHeader(const void* pTexPackage)
145 {
146     if(!pTexPackage)
147     {
148         NN_TASSERT_(pTexPackage != 0);
149         return false;
150     }
151 
152     // 指定された番号がテクスチャの枚数に収まっているか確認。
153     const CtrTexturePackageHeader *header =
154         reinterpret_cast<const CtrTexturePackageHeader *>(pTexPackage);
155     NN_TASSERT_(header);
156 
157     // ヘッダのマジックコードを確認。
158     if(::std::strncmp(header->magic, "CTPK", 4) != 0)
159     {
160         NN_LOG("ERROR: The texture package's magic code isn't 'CTPK'.\n");
161         return false;
162     }
163 
164     if(header->version != CTR_TEXTURE_PACKAGE_VERSION)
165     {
166         NN_LOG("ERROR: The texture package's version code differs.\n");
167         return false;
168     }
169 
170     return true;
171 }
172 
173 
174 }}}
175