// ReadNpk.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // static void ReadColor(BYTE* Tab, int Type, BYTE* SaveByte, int Offset) { BYTE a = 0; BYTE r = 0; BYTE g = 0; BYTE b = 0; switch (Type) { case 0x0e: a = (byte)(Tab[1] >> 7); r = (byte)((Tab[1] >> 2) & 0x1f); g = (byte)((Tab[0] >> 5) | ((Tab[1] & 3) << 3)); b = (byte)(Tab[0] & 0x1f); a = (byte)(a * 0xff); r = (byte)((r << 3) | (r >> 2)); g = (byte)((g << 3) | (g >> 2)); b = (byte)((b << 3) | (b >> 2)); break; case 0x0f: a = (byte)(Tab[1] & 0xf0); r = (byte)((Tab[1] & 0xf) << 4); g = (byte)(Tab[0] & 0xf0); b = (byte)((Tab[0] & 0xf) << 4); break; } SaveByte[Offset + 0] = b; SaveByte[Offset + 1] = g; SaveByte[Offset + 2] = r; SaveByte[Offset + 3] = a; } class ReadNpk :public std::ifstream { const BYTE Key[256] = { 112,117,99,104,105,107,111,110,64,110,101,111,112,108,101,32,100,117,110,103,101,111,110,32,97,110,100,32,102,105,103,104,116,101,114,32,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,0 }; public: //char* 转整数 int CharToInt(char* Str) { return *(int*)Str; } //char* 转Long long long CharToLong(char* Str) { return *(long long*)Str; } //读整数 int ReadInt() { char* CountBuffer = new char[4]; for (int i = 0; i < 4; i++) { this->get(CountBuffer[i]); } int Count = CharToInt(CountBuffer); delete[]CountBuffer; return Count; } //读字符串 std::string ReadString() { char* CharBuffer = new char[1024]; this->get(CharBuffer, 1024, '\0'); std::string Str = CharBuffer; delete[]CharBuffer; this->seekg(1, std::ios::cur); return Str; } //读取信息 std::string ReadInfo() { char* CharBuffer = new char[256]; char var; int i = 0; while (i < 256) { this->get(var); CharBuffer[i] = var ^ Key[i]; ++i; } std::string Str = CharBuffer; delete[] CharBuffer; return Str; } //读LONG long long ReadLong() { char* CountBuffer = new char[8]; for (int i = 0; i < 8; i++) { this->get(CountBuffer[i]); } long long Count = CharToLong(CountBuffer); delete[]CountBuffer; return Count; } //读指定长度数据 BYTE* ReadCustomSize(int Size) { BYTE* CharBuffer = new BYTE[Size]; for (int j = 0; j < Size; j++) { char var; this->get(var); CharBuffer[j] = var; } return CharBuffer; } }; struct NpkInfo { int Offset; int Length; std::string Path; }; struct ImgInfo { //图片格式 int Type; //压缩类型 int CmpType; //宽度 int Width; //高度 int Height; //大小 int Size; //Xpos int Xpos; //Ypos int Ypos; //帧域X int FrameXpos; //帧域Y int FrameYpos; //偏移 int Offset; }; // xxxx.img 5 static BYTE* GetNPK() { typedef int (*__Decompress)(BYTE* dest, ULONG* destLen, BYTE* source, ULONG sourceLen); HMODULE hDll = LoadLibrary(L"zlib1.dll"); __Decompress Decompress = (__Decompress)GetProcAddress(hDll, "uncompress"); ReadNpk Fs; Fs.open("!HUD_阿拉德猜数字.NPK", std::ios::in | std::ios::binary); if (Fs) { std::string Header = Fs.ReadString(); //如果是NPK if (Header._Equal("NeoplePack_Bill")) { int Count = Fs.ReadInt(); std::cout << "img数量:" << Count << std::endl; //new出 img数量的 结构体 NpkInfo* ImgList = new NpkInfo[Count]; //读取 img列表数据 for (int i = 0; i < Count; i++) { ImgList[i].Offset = Fs.ReadInt(); ImgList[i].Length = Fs.ReadInt(); ImgList[i].Path = Fs.ReadInfo(); } for (int z = 0; z < Count; z++) { Fs.seekg(ImgList[z].Offset); std::string Flag = Fs.ReadString(); if (Flag._Equal("Neople Img File")) { //索引表大小 long long TableLength = Fs.ReadLong(); //img 版本 4字节 int ver = Fs.ReadInt(); //img 帧数 int IndexCount = Fs.ReadInt(); //new出 Png数量的 结构体 ImgInfo* PngList = new ImgInfo[IndexCount]; for (int i = 0; i < IndexCount; i++) { PngList[i].Type = Fs.ReadInt(); if (PngList[i].Type == 17) { //引用贴图 std::cout << Fs.ReadInt() << std::endl; continue; } //压缩类型 PngList[i].CmpType = Fs.ReadInt(); //宽度 PngList[i].Width = Fs.ReadInt(); //高度 PngList[i].Height = Fs.ReadInt(); //大小 PngList[i].Size = Fs.ReadInt(); //Xpos PngList[i].Xpos = Fs.ReadInt(); //Ypos PngList[i].Ypos = Fs.ReadInt(); //帧域X PngList[i].FrameXpos = Fs.ReadInt(); //帧域Y PngList[i].FrameYpos = Fs.ReadInt(); //计算偏移 if (i == 0)PngList[i].Offset = 0 + ImgList[z].Offset + TableLength + 32; else PngList[i].Offset = PngList[i - 1].Offset + PngList[i - 1].Size; } Fs.seekg(PngList[0].Offset); std::cout << PngList[0].Size << std::endl; BYTE* PngData = Fs.ReadCustomSize(PngList[0].Size); int DeSize = PngList[0].Width * PngList[0].Height * 4; BYTE* bByte = new BYTE[DeSize]; ULONG RealSize; int a = Decompress(bByte, &RealSize, PngData, (ULONG)PngList[0].Size); delete[]PngData; if (PngList[0].Type != 16) { int PngByteSize = DeSize * 2; BYTE* PngByte = new BYTE[PngByteSize]; for (int e = 0; e < PngByteSize; e += 4) { BYTE NeedData[4]; memset(NeedData, 0, sizeof(NeedData)); memcpy(NeedData, bByte + e, sizeof(NeedData)); ReadColor(NeedData, PngList[0].Type, PngByte, e); } delete[]bByte; for (int o = 0; o < PngByteSize; o++) { //std::cout << (int)PngByte[o] << ","; } delete[]PngByte; } return bByte; delete[] bByte; delete[]PngList; } } //销毁img列表数据 delete[]ImgList; //销毁Png列表数据 } } else { std::cout << "打开失败" << std::endl; } Fs.close(); return 0; }