293 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C++
		
	
	
	
		
		
			
		
	
	
			293 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C++
		
	
	
	
|  | // ReadNpk.cpp : <20><><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD> "main" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD>н<EFBFBD><D0BD>ڴ˴<DAB4><CBB4><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | |||
|  | //
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 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* ת<><D7AA><EFBFBD><EFBFBD>
 | |||
|  |     int CharToInt(char* Str) | |||
|  |     { | |||
|  |         return *(int*)Str; | |||
|  |     } | |||
|  | 
 | |||
|  |     //char* תLong
 | |||
|  |     long long CharToLong(char* Str) | |||
|  |     { | |||
|  |         return *(long long*)Str; | |||
|  |     } | |||
|  | 
 | |||
|  | 
 | |||
|  |     //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | |||
|  |     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; | |||
|  |     } | |||
|  | 
 | |||
|  |     //<2F><><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
 | |||
|  |     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; | |||
|  |     } | |||
|  | 
 | |||
|  |     //<2F><>ȡ<EFBFBD><C8A1>Ϣ
 | |||
|  |     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; | |||
|  |     } | |||
|  | 
 | |||
|  |     //<2F><>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; | |||
|  |     } | |||
|  | 
 | |||
|  |     //<2F><>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | |||
|  |     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 | |||
|  | { | |||
|  |     //ͼƬ<CDBC><C6AC>ʽ
 | |||
|  |     int Type; | |||
|  |     //ѹ<><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | |||
|  |     int CmpType; | |||
|  |     //<2F><><EFBFBD><EFBFBD>
 | |||
|  |     int Width; | |||
|  |     //<2F>߶<EFBFBD>
 | |||
|  |     int Height; | |||
|  |     //<2F><>С
 | |||
|  |     int Size; | |||
|  |     //Xpos
 | |||
|  |     int Xpos; | |||
|  |     //Ypos
 | |||
|  |     int Ypos; | |||
|  |     //֡<><D6A1>X
 | |||
|  |     int FrameXpos; | |||
|  |     //֡<><D6A1>Y
 | |||
|  |     int FrameYpos; | |||
|  |     //ƫ<><C6AB>
 | |||
|  |     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_<44><5F><EFBFBD><EFBFBD><EFBFBD>²<EFBFBD><C2B2><EFBFBD><EFBFBD><EFBFBD>.NPK", std::ios::in | std::ios::binary); | |||
|  | 
 | |||
|  |     if (Fs) | |||
|  |     { | |||
|  | 
 | |||
|  |         std::string Header = Fs.ReadString(); | |||
|  |         //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>NPK
 | |||
|  |         if (Header._Equal("NeoplePack_Bill")) | |||
|  |         { | |||
|  |             int Count = Fs.ReadInt(); | |||
|  |             std::cout << "img<EFBFBD><EFBFBD><EFBFBD><EFBFBD>:" << Count << std::endl; | |||
|  | 
 | |||
|  |             //new<65><77> img<6D><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ṹ<EFBFBD><E1B9B9>
 | |||
|  |             NpkInfo* ImgList = new NpkInfo[Count]; | |||
|  |             //<2F><>ȡ img<6D>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD>
 | |||
|  |             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")) | |||
|  |                 { | |||
|  |                     //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
 | |||
|  |                     long long TableLength = Fs.ReadLong(); | |||
|  |                     //img <20>汾 4<>ֽ<EFBFBD>
 | |||
|  |                     int ver = Fs.ReadInt(); | |||
|  |                     //img ֡<><D6A1>
 | |||
|  |                     int IndexCount = Fs.ReadInt(); | |||
|  | 
 | |||
|  |                     //new<65><77> Png<6E><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ṹ<EFBFBD><E1B9B9>
 | |||
|  |                     ImgInfo* PngList = new ImgInfo[IndexCount]; | |||
|  |                     for (int i = 0; i < IndexCount; i++) | |||
|  |                     { | |||
|  |                         PngList[i].Type = Fs.ReadInt(); | |||
|  |                         if (PngList[i].Type == 17) | |||
|  |                         { | |||
|  |                             //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ
 | |||
|  |                             std::cout << Fs.ReadInt() << std::endl; | |||
|  |                             continue; | |||
|  |                         } | |||
|  |                         //ѹ<><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | |||
|  |                         PngList[i].CmpType = Fs.ReadInt(); | |||
|  |                         //<2F><><EFBFBD><EFBFBD>
 | |||
|  |                         PngList[i].Width = Fs.ReadInt(); | |||
|  |                         //<2F>߶<EFBFBD>
 | |||
|  |                         PngList[i].Height = Fs.ReadInt(); | |||
|  |                         //<2F><>С
 | |||
|  |                         PngList[i].Size = Fs.ReadInt(); | |||
|  |                         //Xpos
 | |||
|  |                         PngList[i].Xpos = Fs.ReadInt(); | |||
|  |                         //Ypos
 | |||
|  |                         PngList[i].Ypos = Fs.ReadInt(); | |||
|  |                         //֡<><D6A1>X
 | |||
|  |                         PngList[i].FrameXpos = Fs.ReadInt(); | |||
|  |                         //֡<><D6A1>Y
 | |||
|  |                         PngList[i].FrameYpos = Fs.ReadInt(); | |||
|  |                         //<2F><><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB>
 | |||
|  |                         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; | |||
|  |                 } | |||
|  |             } | |||
|  | 
 | |||
|  |             //<2F><><EFBFBD><EFBFBD>img<6D>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD>
 | |||
|  |             delete[]ImgList; | |||
|  |             //<2F><><EFBFBD><EFBFBD>Png<6E>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD>
 | |||
|  |         } | |||
|  |     } | |||
|  |     else | |||
|  |     { | |||
|  |         std::cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>" << std::endl; | |||
|  |     } | |||
|  |     Fs.close(); | |||
|  |     return 0; | |||
|  | } | |||
|  | 
 |