From c943efbec04956bd8b9867ce949f78817dcc0803 Mon Sep 17 00:00:00 2001 From: def Date: Mon, 12 Jun 2017 21:00:13 +0200 Subject: [PATCH] Add tool to extract images and sounds from maps --- src/tools/map_extract.cpp | 114 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 src/tools/map_extract.cpp diff --git a/src/tools/map_extract.cpp b/src/tools/map_extract.cpp new file mode 100644 index 000000000..4579a6381 --- /dev/null +++ b/src/tools/map_extract.cpp @@ -0,0 +1,114 @@ +// Adapted from TWMapImagesRecovery by Tardo: https://github.com/Tardo/TWMapImagesRecovery +#include +#include +#include +#include +#include + +bool Process(IStorage *pStorage, const char *pMapName, const char *pPathSave) +{ + CDataFileReader Map; + + if(!Map.Open(pStorage, pMapName, IStorage::TYPE_ALL)) + { + dbg_msg("map_extract", "error opening map '%s'", pMapName); + return false; + } + + + // check version + CMapItemVersion *pVersion = (CMapItemVersion *)Map.FindItem(MAPITEMTYPE_VERSION, 0); + if(pVersion && pVersion->m_Version != 1) + return false; + + dbg_msg("map_extract", "Make sure you have the permission to use these images and sounds in your own maps"); + + CMapItemInfo *pInfo = (CMapItemInfo *)Map.FindItem(MAPITEMTYPE_INFO, 0); + + dbg_msg("map_extract", "author: %s", Map.GetData(pInfo->m_Author)); + dbg_msg("map_extract", "version: %s", Map.GetData(pInfo->m_MapVersion)); + dbg_msg("map_extract", "credits: %s", Map.GetData(pInfo->m_Credits)); + dbg_msg("map_extract", "license: %s", Map.GetData(pInfo->m_License)); + + int Start, Num; + + // load images + Map.GetType(MAPITEMTYPE_IMAGE, &Start, &Num); + + for(int i = 0; i < Num; i++) + { + CMapItemImage *pItem = (CMapItemImage *)Map.GetItem(Start+i, 0, 0); + char *pName = (char *)Map.GetData(pItem->m_ImageName); + + if(pItem->m_External) + continue; + + char aBuf[512]; + str_format(aBuf, sizeof(aBuf), "%s/%s.png", pPathSave, pName); + dbg_msg("map_extract", "writing image: %s (%dx%d)", aBuf, pItem->m_Width, pItem->m_Height); + + // copy image data + png_t Png; + png_open_file_write(&Png, aBuf); + png_set_data(&Png, pItem->m_Width, pItem->m_Height, 8, PNG_TRUECOLOR_ALPHA, (unsigned char*)Map.GetData(pItem->m_ImageData)); + png_close_file(&Png); + } + + // load sounds + Map.GetType(MAPITEMTYPE_SOUND, &Start, &Num); + + for(int i = 0; i < Num; i++) + { + CMapItemSound *pItem = (CMapItemSound *)Map.GetItem(Start+i, 0, 0); + char *pName = (char *)Map.GetData(pItem->m_SoundName); + + if(pItem->m_External) + continue; + + char aBuf[512]; + str_format(aBuf, sizeof(aBuf), "%s/%s.opus", pPathSave, pName); + dbg_msg("map_extract", "writing sound: %s (%d B)", aBuf, pItem->m_SoundDataSize); + + IOHANDLE Opus = io_open(aBuf, IOFLAG_WRITE); + io_write(Opus, (unsigned char*)Map.GetData(pItem->m_SoundData), pItem->m_SoundDataSize); + io_close(Opus); + } + + return Map.Close(); +} + +int main(int argc, char* argv[]) +{ + dbg_logger_stdout(); + + char aMap[512]; + char aDir[512]; + + IStorage *pStorage = CreateLocalStorage(); + + if (argc == 2) + { + str_copy(aMap, argv[1], sizeof(aMap)); + str_copy(aDir, ".", sizeof(aMap)); + } + else if (argc == 3) + { + str_copy(aMap, argv[1], sizeof(aMap)); + str_copy(aDir, argv[2], sizeof(aDir)); + } + else + { + dbg_msg("usage", "%s ", argv[0]); + return -1; + } + + if (!fs_is_dir(aDir)) + { + dbg_msg("usage" "directory '%s' does not exist", aDir); + return -1; + } + + png_init(0, 0); + + return Process(pStorage, aMap, aDir) ? 0 : 1; +}