1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     tpl_ReadTexturePackage.cpp
4 
5   Copyright (C)2009-2012 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: 46347 $
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 // Gets the number of textures included in the texture package file.
GetTextureNum(const void * pTexPackage)28 u16 GetTextureNum(const void* pTexPackage)
29 {
30     if (pTexPackage == NULL)
31     {
32         NN_NULL_TASSERT_(pTexPackage);
33         return 0;
34     }
35     const CtrTexturePackageHeader* header =
36         reinterpret_cast<const CtrTexturePackageHeader*>(pTexPackage);
37     return header->numTexture;
38 }
39 
40 // Function to get the texture index
GetTextureIndex(const void * pTexPackage,const char * texPath)41 s16 GetTextureIndex(const void* pTexPackage, const char* texPath)
42 {
43     if(pTexPackage == NULL || texPath == NULL)
44     {
45         NN_NULL_TASSERT_(pTexPackage);
46         NN_NULL_TASSERT_(texPath);
47         return -1;
48     }
49     // Creates the CRC32 hash code.
50     int fileNameLen = (int)::std::strlen(texPath);
51     unsigned int crc32key = calculate_crc32(texPath, fileNameLen);
52 
53     const CtrTexturePackageHeader &header =
54         *reinterpret_cast<const CtrTexturePackageHeader *>(pTexPackage);
55     const CtrTextureHash *texHash = reinterpret_cast<const CtrTextureHash *>
56                       ((const char*)pTexPackage + (header.texHashOffset));
57 
58     // Compares to texture information in the package and searches for matches.
59     TPK_SEARCH_DATA data = { texPath, fileNameLen, pTexPackage };
60     int t = search_crc32_data(
61         texHash, header.numTexture, sizeof(CtrTextureHash), crc32key, &data);
62 
63     if(t < 0) return -1;
64     return texHash[t].index;
65 }
66 
67 // Function to get texture
GetTexture(s32 * mipLevel,u32 * mipmapSize,const void * pTexPackage,const s16 texIndex)68 void* GetTexture(s32* mipLevel, u32* mipmapSize, const void* pTexPackage, const s16 texIndex)
69 {
70     if( mipLevel == NULL || mipmapSize == NULL || pTexPackage == NULL )
71     {
72         NN_NULL_TASSERT_(mipLevel);
73         NN_NULL_TASSERT_(mipmapSize);
74         NN_NULL_TASSERT_(pTexPackage);
75         return 0;
76     }
77 
78     // Confirms that the specified number is included in the number of textures.
79     const CtrTexturePackageHeader *header =
80         reinterpret_cast<const CtrTexturePackageHeader *>(pTexPackage);
81     NN_TASSERT_((0 <= texIndex) && (texIndex < header->numTexture));
82     if((texIndex < 0) || (header->numTexture <= texIndex))
83     {
84         return 0;
85     }
86 
87     const CtrTextureInfo *texInfo = reinterpret_cast<const CtrTextureInfo *>
88         (((const char*)pTexPackage) + (sizeof(CtrTexturePackageHeader)) + (sizeof(CtrTextureInfo) * texIndex));
89 
90     if(texInfo == NULL)
91     {
92         return 0;
93     }
94 
95     // get texture size.
96     const unsigned int *Size = reinterpret_cast<const unsigned int *>
97         (((const char*)pTexPackage) + (4 * texInfo->bitmapSizeOffset));
98 
99     *mipLevel = static_cast<int>(texInfo->mipLevel);
100     for(int i=0; i < *mipLevel; i++)
101     {
102         mipmapSize[i] = Size[i];
103     }
104 
105     return (void*)(((const char*)pTexPackage) + (header->texDataOffset + texInfo->texDataOffset));
106 }
107 
108 // Function to get texture information
GetTextureInfo(CtrTextureInfo * pTexInfo,const void * pTexPackage,const s16 texIndex)109 bool GetTextureInfo(CtrTextureInfo* pTexInfo, const void* pTexPackage, const s16 texIndex)
110 {
111     if(pTexPackage == NULL || pTexInfo == NULL)
112     {
113         NN_NULL_TASSERT_(pTexPackage);
114         NN_NULL_TASSERT_(pTexInfo);
115         return false;
116     }
117 
118 
119     // Confirms that the specified number is included in the number of textures.
120     const CtrTexturePackageHeader *header =
121         reinterpret_cast<const CtrTexturePackageHeader *>(pTexPackage);
122     NN_TASSERT_((0 <= texIndex) && (texIndex < header->numTexture));
123     if((texIndex < 0) || (header->numTexture <= texIndex))
124     {
125         return false;
126     }
127 
128     const CtrTextureInfo *texInfo = reinterpret_cast<const CtrTextureInfo *>
129         (((const char*)pTexPackage) + (sizeof(CtrTexturePackageHeader)) + (sizeof(CtrTextureInfo) * texIndex));
130 
131     pTexInfo->filePathOffset   = texInfo->filePathOffset;
132     pTexInfo->texDataSize      = texInfo->texDataSize;
133     pTexInfo->texDataOffset    = texInfo->texDataOffset;
134     pTexInfo->texFormat        = texInfo->texFormat;
135     pTexInfo->width            = texInfo->width;
136     pTexInfo->height           = texInfo->height;
137     pTexInfo->mipLevel         = texInfo->mipLevel;
138     pTexInfo->type             = texInfo->type;
139     pTexInfo->cubeDir          = texInfo->cubeDir;
140     pTexInfo->bitmapSizeOffset = texInfo->bitmapSizeOffset;
141     pTexInfo->srcFileTime      = texInfo->srcFileTime;
142 
143     return true;
144 }
145 
146 
147 // Function to check the texture package header (helper function)
CheckTexturePackageHeader(const void * pTexPackage)148 bool CheckTexturePackageHeader(const void* pTexPackage)
149 {
150     if(pTexPackage == NULL)
151     {
152         NN_NULL_TASSERT_(pTexPackage);
153         return false;
154     }
155 
156     // Confirms that the specified number is included in the number of textures.
157     const CtrTexturePackageHeader *header =
158         reinterpret_cast<const CtrTexturePackageHeader *>(pTexPackage);
159     NN_NULL_TASSERT_(header);
160 
161     // Confirms header magic code.
162     if(::std::strncmp(header->magic, "CTPK", 4) != 0)
163     {
164         NN_LOG("ERROR: The texture package's magic code isn't 'CTPK'.\n");
165         return false;
166     }
167 
168     if(header->version != CTR_TEXTURE_PACKAGE_VERSION)
169     {
170         NN_LOG("ERROR: The texture package's version code differs.\n");
171         return false;
172     }
173 
174     return true;
175 }
176 
177 
178 }}}
179