bool GWriteBitmapToFile(const GBitmap& bitmap, const char path[]) { FILE* f = ::fopen(path, "wb"); if (!f) { return false; } GAutoFClose afc(f); png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { return false; } png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, NULL); return false; } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); return false; } png_init_io(png_ptr, f); if (setjmp(png_jmpbuf(png_ptr))) { return false; } const int bitDepth = 8; png_set_IHDR(png_ptr, info_ptr, bitmap.fWidth, bitmap.fHeight, bitDepth, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png_ptr, info_ptr); char* scanline = (char*)malloc(bitmap.fWidth * 4); GAutoFree gaf(scanline); const GPixel* srcRow = bitmap.fPixels; for (int y = 0; y < bitmap.fHeight; y++) { convertToPNG(srcRow, bitmap.fWidth, scanline); png_bytep row_ptr = (png_bytep)scanline; png_write_rows(png_ptr, &row_ptr, 1); srcRow = (const GPixel*)((const char*)srcRow + bitmap.fRowBytes); } png_write_end(png_ptr, NULL); png_destroy_write_struct(&png_ptr, &info_ptr); return true; }
Material Model::loadMaterial( std::string& data, int numOfTextures, int programID ) { Material material( programID ); for( unsigned int i = 0; i < data.length(); ++i ) { std::string line; while( data[i] != '\n' ) { line += data[i]; ++i; } StringParser lineParser( line, std::string( ", " ) ); int textureType = atoi( lineParser.getNextToken().c_str() ); std::string fileName = lineParser.getNextToken(); std::string filePath( "Models\\Images\\" ); if( fileName.length() == 0 ) return material; std::string extension = fileName.substr( fileName.length() - 3, 3 ); if( extension.compare( "dds" ) == 0 ) { convertToPNG( fileName ); } switch( textureType ) { case DIFFUSE: material.setTexture( std::string( "diffuseTex" ), GL_TEXTURE0, Texture::CreateOrGetTexture( filePath + fileName )->getTextureID() ); break; case SPECULAR: material.setTexture( std::string( "specularTex" ), GL_TEXTURE1, Texture::CreateOrGetTexture( filePath + fileName )->getTextureID() ); break; case EMISSIVE: material.setTexture( std::string( "emissiveTex" ), GL_TEXTURE2, Texture::CreateOrGetTexture( filePath + fileName )->getTextureID() ); break; case NORMAL: material.setTexture( std::string( "normalTex" ), GL_TEXTURE3, Texture::CreateOrGetTexture( filePath + fileName )->getTextureID() ); break; } } return material; }
int main(int argc, char* argv[]) { init_libxpwn(&argc, argv); if(argc < 4) { print_usage(); return 0; } AbstractFile* png; AbstractFile* img; AbstractFile* dst; void* imageBuffer; size_t imageSize; unsigned int key[32]; unsigned int iv[16]; unsigned int* pKey = NULL; unsigned int* pIV = NULL; if(strcmp(argv[1], "inject") == 0) { if(argc < 5) { print_usage(); return 0; } png = createAbstractFileFromFile(fopen(argv[2], "rb")); img = createAbstractFileFromFile(fopen(argv[4], "rb")); dst = createAbstractFileFromFile(fopen(argv[3], "wb")); if(argc >= 7) { sscanf(argv[5], "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", &iv[0], &iv[1], &iv[2], &iv[3], &iv[4], &iv[5], &iv[6], &iv[7], &iv[8], &iv[9], &iv[10], &iv[11], &iv[12], &iv[13], &iv[14], &iv[15]); sscanf(argv[6], "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", &key[0], &key[1], &key[2], &key[3], &key[4], &key[5], &key[6], &key[7], &key[8], &key[9], &key[10], &key[11], &key[12], &key[13], &key[14], &key[15], &key[16], &key[17], &key[18], &key[19], &key[20], &key[21], &key[22], &key[23], &key[24], &key[25], &key[26], &key[27], &key[28], &key[29], &key[30], &key[31]); pKey = key; pIV = iv; } imageBuffer = replaceBootImage(img, pKey, pIV, png, &imageSize); dst->write(dst, imageBuffer, imageSize); dst->close(dst); } else if(strcmp(argv[1], "extract") == 0) { img = createAbstractFileFromFile(fopen(argv[2], "rb")); if(argc >= 6) { sscanf(argv[4], "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", &iv[0], &iv[1], &iv[2], &iv[3], &iv[4], &iv[5], &iv[6], &iv[7], &iv[8], &iv[9], &iv[10], &iv[11], &iv[12], &iv[13], &iv[14], &iv[15]); sscanf(argv[5], "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", &key[0], &key[1], &key[2], &key[3], &key[4], &key[5], &key[6], &key[7], &key[8], &key[9], &key[10], &key[11], &key[12], &key[13], &key[14], &key[15], &key[16], &key[17], &key[18], &key[19], &key[20], &key[21], &key[22], &key[23], &key[24], &key[25], &key[26], &key[27], &key[28], &key[29], &key[30], &key[31]); pKey = key; pIV = iv; } if(convertToPNG(img, pKey, pIV, argv[3]) < 0) { XLOG(1, "error converting img to png"); } } return 0; }
void decompressResource() { for(bool bDone = false;!bDone;) //Loop until we're done { ThreadConvertHelper dh; wstring sFilename; std::lock_guard<std::mutex> lock(g_Mutex); if(!g_lThreadedResources.size()) //Done { bDone = true; } else { //Grab the top item off the list dh = g_lThreadedResources.front(); sFilename = getName(dh.id); //Mutex on this too, since getName() isn't really threadsafe makeFolder(dh.id); //Also create folder (not threadsafe, either) g_lThreadedResources.pop_front(); //Done with this element } //Let user know which resource we're converting now if(!bDone) { g_iCurResource++; if(!(sFilename == RESIDMAP_NAME && g_iCurResource == 1)) { if(g_bProgressOverwrite) { cout << "\rDecompressing file " << g_iCurResource << " out of " << g_iNumResources; cout.flush(); } else cout << "Decompressing file " << g_iCurResource << " out of " << g_iNumResources << ": " << ws2s(sFilename) << endl; } } // Release ownership of the mutex object if(sFilename == RESIDMAP_NAME && g_iCurResource == 1) //Don't release residmap.dat mutex until we've read in all the filenames { g_iNumResources--; } if(bDone) { continue; //Stop here if done } if(dh.bCompressed) //Compressed { uint8_t* tempData = decompress(&dh.data); if(tempData == NULL) { cout << "Error decompressing file " << ws2s(sFilename) << endl; return; } free(dh.data.data); //Free this compressed memory dh.data.data = tempData; //Now we have the decompressed data } //See if this was a PNG image. Convert PNG images from the data in RAM if(sFilename.find(L".png") != wstring::npos || sFilename.find(L".PNG") != wstring::npos || sFilename.find(L"coloritemicon") != wstring::npos || sFilename.find(L"colorbgicon") != wstring::npos || sFilename.find(L"greybgicon") != wstring::npos) //Also would include .png.normal files as well { convertToPNG(sFilename.c_str(), dh.data.data, dh.data.decompressedSize); //Do the conversion to PNG } else //For other file types, go ahead and write to the file before converting { //Write this out to the file FILE* fOut = fopen(ws2s(sFilename).c_str(), "wb"); if(fOut == NULL) { cout << "Unable to open output file " << ws2s(sFilename) << endl; return; } fwrite(dh.data.data, 1, dh.data.decompressedSize, fOut); fclose(fOut); } free(dh.data.data); //Free memory from this file /* //Convert wordPackDict.dat to XML if(sFilename.find(L"wordPackDict.dat") != wstring::npos) { wordPackToXML(sFilename.c_str()); unlink(ws2s(sFilename).c_str()); } //Convert sndmanifest.dat to XML else if(sFilename.find(L"sndmanifest.dat") != wstring::npos) { sndManifestToXML(sFilename.c_str()); unlink(ws2s(sFilename).c_str()); } //Convert itemmanifest.dat to XML else if(sFilename.find(L"itemmanifest.dat") != wstring::npos) { itemManifestToXML(sFilename.c_str()); unlink(ws2s(sFilename).c_str()); } //Convert letterdb.dat to XML else if(sFilename.find(L"letterdb.dat") != wstring::npos) { letterToXML(sFilename.c_str()); unlink(ws2s(sFilename).c_str()); } //Convert catalogdb.dat to XML else if(sFilename.find(L"catalogdb.dat") != wstring::npos) { catalogToXML(sFilename.c_str()); unlink(ws2s(sFilename).c_str()); } //Convert combodb.dat to XML else if(sFilename.find(L"combodb.dat") != wstring::npos) { comboDBToXML(sFilename.c_str()); unlink(ws2s(sFilename).c_str()); } //Convert residmap.dat to XML else if(sFilename.find(L"residmap.dat") != wstring::npos) { residMapToXML(sFilename.c_str()); unlink(ws2s(sFilename).c_str()); } //Convert .flac binary files to OGG else if(sFilename.find(L".flac") != wstring::npos || sFilename.find(L".FLAC") != wstring::npos) { wstring s = sFilename; s += L".ogg"; binaryToOgg(sFilename.c_str(), s.c_str()); unlink(ws2s(sFilename).c_str()); //Delete temporary .flac file } //Convert vdata/fontmanifest.dat to XML else if(sFilename.find(L"fontmanifest.dat") != wstring::npos) { fontManifestToXML(sFilename); unlink(ws2s(sFilename).c_str()); } //Convert font files to XML else if(sFilename.find(L".font.xml") != wstring::npos) { fontToXML(sFilename); } //Convert vdata/loctexmanifest.bin to XML else if(sFilename.find(L"loctexmanifest.bin") != wstring::npos) { LoctexManifestToXML(sFilename); unlink(ws2s(sFilename).c_str()); } //Convert vdata/myPicturesImage.dat to XML else if(sFilename.find(L"myPicturesImage.dat") != wstring::npos) { myPicturesToXML(sFilename); unlink(ws2s(sFilename).c_str()); } //Convert vdata/smokeImage.dat to XML else if(sFilename.find(L"smokeImage.dat") != wstring::npos) { smokeImageToXML(sFilename); unlink(ws2s(sFilename).c_str()); } //Convert vdata/fluidPalettes.dat to XML else if(sFilename.find(L"fluidPalettes.dat") != wstring::npos) { fluidPalettesToXML(sFilename); unlink(ws2s(sFilename).c_str()); } */ if(sFilename == RESIDMAP_NAME && g_iCurResource == 1) { g_iCurResource--; } } return; }
DWORD WINAPI decompressResource(LPVOID lpParam) { for(bool bDone = false;!bDone;) //Loop until we're done { ThreadConvertHelper dh; DWORD dwWaitResult = WaitForSingleObject(ghMutex, // wait for mutex INFINITE); // no time-out interval switch (dwWaitResult) { // The thread got ownership of the mutex case WAIT_OBJECT_0: if(!g_lThreadedResources.size()) //Done bDone = true; else { //Grab the top item off the list dh = g_lThreadedResources.front(); g_lThreadedResources.pop_front(); //Done with this element } //Let user know which resource we're converting now if(!bDone) { if(g_bProgressOverwrite) { cout << "\rDecompressing file " << ++g_iCurResource << " out of " << g_iNumResources; cout.flush(); } else cout << "Decompressing file " << ++g_iCurResource << " out of " << g_iNumResources << ": " << ws2s(dh.sFilename) << endl; } // Release ownership of the mutex object if (!ReleaseMutex(ghMutex)) { cout << "Error: Unable to release mutex." << endl; return 1; } break; // The thread got ownership of an abandoned mutex // This is an indeterminate state case WAIT_ABANDONED: cout << "Error: Abandoned mutex" << endl; return 1; } if(bDone) continue; //Stop here if done if(dh.bCompressed) //Compressed { uint8_t* tempData = decompress(&dh.data); if(tempData == NULL) { cout << "Error decompressing file " << ws2s(dh.sFilename) << endl; return 1; } free(dh.data.data); //Free this compressed memory dh.data.data = tempData; //Now we have the decompressed data } //See if this was a PNG image. Convert PNG images from the data in RAM if(dh.sFilename.find(TEXT(".png")) != wstring::npos || dh.sFilename.find(TEXT(".PNG")) != wstring::npos || dh.sFilename.find(TEXT("coloritemicon")) != wstring::npos || dh.sFilename.find(TEXT("colorbgicon")) != wstring::npos || dh.sFilename.find(TEXT("greybgicon")) != wstring::npos) //Also would include .png.normal files as well { convertToPNG(dh.sFilename.c_str(), dh.data.data, dh.data.decompressedSize); //Do the conversion to PNG } else //For other file types, go ahead and write to the file before converting { //Write this out to the file FILE* fOut = _wfopen(dh.sFilename.c_str(), TEXT("wb")); if(fOut == NULL) { cout << "Unable to open output file " << ws2s(dh.sFilename) << endl; return 1; } fwrite(dh.data.data, 1, dh.data.decompressedSize, fOut); fclose(fOut); } free(dh.data.data); //Free memory from this file //Convert wordPackDict.dat to XML if(dh.sFilename.find(TEXT("wordPackDict.dat")) != wstring::npos) { wordPackToXML(dh.sFilename.c_str()); unlink(ws2s(dh.sFilename).c_str()); } //Convert sndmanifest.dat to XML else if(dh.sFilename.find(TEXT("sndmanifest.dat")) != wstring::npos) { sndManifestToXML(dh.sFilename.c_str()); unlink(ws2s(dh.sFilename).c_str()); } //Convert itemmanifest.dat to XML else if(dh.sFilename.find(TEXT("itemmanifest.dat")) != wstring::npos) { itemManifestToXML(dh.sFilename.c_str()); //TODO unlink(ws2s(dh.sFilename).c_str()); } //Convert residmap.dat to XML else if(dh.sFilename.find(TEXT("residmap.dat")) != wstring::npos) { residMapToXML(dh.sFilename.c_str()); unlink(ws2s(dh.sFilename).c_str()); } //Convert .flac binary files to OGG else if(dh.sFilename.find(TEXT(".flac")) != wstring::npos || dh.sFilename.find(TEXT(".FLAC")) != wstring::npos) { wstring s = dh.sFilename; s += TEXT(".ogg"); binaryToOgg(dh.sFilename.c_str(), s.c_str()); unlink(ws2s(dh.sFilename).c_str()); //Delete temporary .flac file } } return 0; }