From 8159450360f60208fc976b097f8d1578936be908 Mon Sep 17 00:00:00 2001 From: Sun Daowen Date: Sat, 29 Jul 2017 13:44:34 +0800 Subject: [PATCH] commandline support unicode --- CMakeLists.txt | 2 +- README.md | 31 +++--- dep/libsundaowen | 2 +- src/CMakeLists.txt | 1 + src/bflim.cpp | 260 +++++++++++++++++++++++---------------------- src/bflim.h | 32 ++++-- src/bflimtool.cpp | 120 ++++++++++----------- src/bflimtool.h | 14 +-- 8 files changed, 239 insertions(+), 223 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f92f4f4..f98a115 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ if(APPLE) endif() set(BFLIMTOOL_MAJOR 1) set(BFLIMTOOL_MINOR 0) -set(BFLIMTOOL_PATCHLEVEL 0) +set(BFLIMTOOL_PATCHLEVEL 1) if(NOT MSVC_IDE AND NOT XCODE_VERSION AND NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel." FORCE) endif() diff --git a/README.md b/README.md index dac64bc..001268c 100644 --- a/README.md +++ b/README.md @@ -5,26 +5,37 @@ A tool for decoding/encoding bflim file. ## History - v1.0.0 @ 2015.03.14 - First release +- v1.0.1 @ 2017.07.29 - Commandline support unicode ## Platforms -- Linux *(Ubuntu 14.04, CentOS 7.0)* -- Mac OS X *10.10* -- Windows *XP+* +- Windows +- Linux +- macOS ## Building ### Dependencies - cmake +- zlib +- libpng ### Compiling +- make 64-bit version ~~~ mkdir project cd project -cmake .. -cmake .. +cmake -DUSE_DEP=OFF .. +make +~~~ + +- make 32-bit version +~~~ +mkdir project +cd project +cmake -DBUILD64=OFF -DUSE_DEP=OFF .. make ~~~ @@ -39,21 +50,15 @@ make install ### Windows ~~~ -bflimtool.exe [option...] [option]... +bflimtool [option...] [option]... ~~~ ### Other ~~~ -bflimtool [option...] [option]... +bflimtool.sh [option...] [option]... ~~~ -> Remember to do `chmod +x bflimtool` first - ## Options See `bflimtool --help` messages. - -## FAQ - -Nothing here for now. diff --git a/dep/libsundaowen b/dep/libsundaowen index 9e95e7b..e9fc8cb 160000 --- a/dep/libsundaowen +++ b/dep/libsundaowen @@ -1 +1 @@ -Subproject commit 9e95e7b1242c83ce6b8f8392bd7210a76e52a40d +Subproject commit e9fc8cbe3451c3d527f4013191acb4da1a68fee3 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 94844da..3cdf4df 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,6 +2,7 @@ AUTO_FILES("." "src" "\\.(cpp|h)$") AUTO_FILES("${ROOT_SOURCE_DIR}/dep/libsundaowen" "src" "\\.(cpp|h)$") include_directories(${DEP_INCLUDE_DIR}) link_directories(${DEP_LIBRARY_DIR}) +add_definitions(-DSDW_MAIN) if(MSVC) string(REPLACE "/MDd" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") diff --git a/src/bflim.cpp b/src/bflim.cpp index ae7e7b8..5f27284 100644 --- a/src/bflim.cpp +++ b/src/bflim.cpp @@ -4,7 +4,7 @@ const u32 CBflim::s_uSignatureBflim = SDW_CONVERT_ENDIAN32('FLIM'); const u32 CBflim::s_uSignatureImage = SDW_CONVERT_ENDIAN32('imag'); -const int CBflim::s_nBPP[] = { 8, 8, 8, 16, 16, 16, 24, 16, 16, 32, 4, 8, 0, 0, 0, 0, 0, 0, 4, 4 }; +const int CBflim::s_nBPP[] = { 8, 8, 8, 16, 16, 16, 24, 16, 16, 32, 4, 8, 4, 4, 0, 0, 0, 0, 4, 4 }; const int CBflim::s_nDecodeTransByte[64] = { 0, 1, 4, 5, 16, 17, 20, 21, @@ -18,10 +18,7 @@ const int CBflim::s_nDecodeTransByte[64] = }; CBflim::CBflim() - : m_pFileName(nullptr) - , m_pPngName(nullptr) - , m_bVerbose(false) - , m_fpBflim(nullptr) + : m_bVerbose(false) { } @@ -29,14 +26,14 @@ CBflim::~CBflim() { } -void CBflim::SetFileName(const char* a_pFileName) +void CBflim::SetFileName(const UString& a_sFileName) { - m_pFileName = a_pFileName; + m_sFileName = a_sFileName; } -void CBflim::SetPngName(const char* a_pPngName) +void CBflim::SetPngName(const UString& a_sPngName) { - m_pPngName = a_pPngName; + m_sPngName = a_sPngName; } void CBflim::SetVerbose(bool a_bVerbose) @@ -47,37 +44,25 @@ void CBflim::SetVerbose(bool a_bVerbose) bool CBflim::DecodeFile() { bool bResult = true; - m_fpBflim = Fopen(m_pFileName, "rb"); - if (m_fpBflim == nullptr) + FILE* fp = UFopen(m_sFileName.c_str(), USTR("rb")); + if (fp == nullptr) { return false; } - Fseek(m_fpBflim, 0, SEEK_END); - n64 nFileSize = Ftell(m_fpBflim); - Fseek(m_fpBflim, 0, SEEK_SET); - u8* pBin = new u8[static_cast(nFileSize)]; - fread(pBin, 1, static_cast(nFileSize), m_fpBflim); - fclose(m_fpBflim); - SBflimHeader* pBflimHeader = reinterpret_cast(pBin + nFileSize - (sizeof(SBflimHeader) + sizeof(SImageBlock))); - SImageBlock* pImageBlock = reinterpret_cast(pBin + nFileSize - sizeof(SImageBlock)); + fseek(fp, 0, SEEK_END); + u32 uBflimSize = ftell(fp); + fseek(fp, 0, SEEK_SET); + u8* pBflim = new u8[uBflimSize]; + fread(pBflim, 1, uBflimSize, fp); + fclose(fp); + SBflimHeader* pBflimHeader = reinterpret_cast(pBflim + uBflimSize - (sizeof(SBflimHeader) + sizeof(SImageBlock))); + SImageBlock* pImageBlock = reinterpret_cast(pBflim + uBflimSize - sizeof(SImageBlock)); do { - if (pImageBlock->Alignment != 0x80) - { - printf("ERROR: unknown alignment %04X", pImageBlock->Alignment); - bResult = false; - break; - } - if (pImageBlock->Rotate != 4 && pImageBlock->Rotate != 8) - { - printf("ERROR: unknown rotate %d", pImageBlock->Rotate); - bResult = false; - break; - } - if (pImageBlock->Format < kTextureFormatL8 || (pImageBlock->Format > kTextureFormatETC1_A4 && pImageBlock->Format < kTextureFormatL4) || pImageBlock->Format > kTextureFormatA4) + if (pImageBlock->Format < kTextureFormatL8 || (pImageBlock->Format > kTextureFormatA4 && pImageBlock->Format < kTextureFormatL4_another) || pImageBlock->Format > kTextureFormatA4_another) { - printf("ERROR: unknown format %d\n\n", pImageBlock->Format); bResult = false; + UPrintf(USTR("ERROR: unknown format %d\n\n"), pImageBlock->Format); break; } n32 nWidth = getBoundSize(pImageBlock->Width); @@ -85,106 +70,94 @@ bool CBflim::DecodeFile() n32 nCheckSize = nWidth * nHeight * s_nBPP[pImageBlock->Format] / 8; if (pImageBlock->ImageSize != nCheckSize && m_bVerbose) { - printf("INFO: width: %X(%X), height: %X(%X), checksize: %X, size: %X, bpp: %d, format: %0X\n", nWidth, pImageBlock->Width, nHeight, pImageBlock->Height, nCheckSize, pImageBlock->ImageSize, pImageBlock->ImageSize * 8 / nWidth / nHeight, pImageBlock->Format); + UPrintf(USTR("INFO: width: %X(%X), height: %X(%X), checksize: %X, size: %X, bpp: %d, format: %0X\n"), nWidth, pImageBlock->Width, nHeight, pImageBlock->Height, nCheckSize, pImageBlock->ImageSize, pImageBlock->ImageSize * 8 / nWidth / nHeight, pImageBlock->Format); } pvrtexture::CPVRTexture* pPVRTexture = nullptr; - if (decode(pBin, nWidth, nHeight, pImageBlock->Format, pImageBlock->Rotate, &pPVRTexture) == 0) + if (decode(pBflim, nWidth, nHeight, pImageBlock->Format, pImageBlock->Flag, &pPVRTexture) == 0) { - FILE* fp = Fopen(m_pPngName, "wb"); + fp = UFopen(m_sPngName.c_str(), USTR("wb")); if (fp == nullptr) { delete pPVRTexture; bResult = false; break; } - png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)nullptr, nullptr, nullptr); - if (png_ptr == nullptr) + png_structp pPng = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); + if (pPng == nullptr) { fclose(fp); delete pPVRTexture; - printf("ERROR: png_create_write_struct error\n\n"); bResult = false; + UPrintf(USTR("ERROR: png_create_write_struct error\n\n")); break; } - png_infop info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == nullptr) + png_infop pInfo = png_create_info_struct(pPng); + if (pInfo == nullptr) { - png_destroy_write_struct(&png_ptr, (png_infopp)nullptr); + png_destroy_write_struct(&pPng, nullptr); fclose(fp); delete pPVRTexture; - printf("ERROR: png_create_info_struct error\n\n"); bResult = false; + UPrintf(USTR("ERROR: png_create_info_struct error\n\n")); break; } - if (setjmp(png_jmpbuf(png_ptr)) != 0) + if (setjmp(png_jmpbuf(pPng)) != 0) { - png_destroy_write_struct(&png_ptr, &info_ptr); + png_destroy_write_struct(&pPng, &pInfo); fclose(fp); delete pPVRTexture; - printf("ERROR: setjmp error\n\n"); bResult = false; + UPrintf(USTR("ERROR: setjmp error\n\n")); break; } - png_init_io(png_ptr, fp); - png_set_IHDR(png_ptr, info_ptr, pImageBlock->Width, pImageBlock->Height, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + png_init_io(pPng, fp); + png_set_IHDR(pPng, pInfo, pImageBlock->Width, pImageBlock->Height, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); u8* pData = static_cast(pPVRTexture->getDataPtr()); png_bytepp pRowPointers = new png_bytep[pImageBlock->Height]; for (n32 i = 0; i < pImageBlock->Height; i++) { pRowPointers[i] = pData + i * nWidth * 4; } - png_set_rows(png_ptr, info_ptr, pRowPointers); - png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, nullptr); - png_destroy_write_struct(&png_ptr, &info_ptr); + png_set_rows(pPng, pInfo, pRowPointers); + png_write_png(pPng, pInfo, PNG_TRANSFORM_IDENTITY, nullptr); + png_destroy_write_struct(&pPng, &pInfo); delete[] pRowPointers; fclose(fp); delete pPVRTexture; } else { - printf("ERROR: decode error\n\n"); bResult = false; + UPrintf(USTR("ERROR: decode error\n\n")); break; } } while (false); - delete[] pBin; + delete[] pBflim; return bResult; } bool CBflim::EncodeFile() { bool bResult = true; - m_fpBflim = Fopen(m_pFileName, "rb"); - if (m_fpBflim == nullptr) + FILE* fp = UFopen(m_sFileName.c_str(), USTR("rb")); + if (fp == nullptr) { return false; } - Fseek(m_fpBflim, 0, SEEK_END); - n64 nFileSize = Ftell(m_fpBflim); - Fseek(m_fpBflim, 0, SEEK_SET); - u8* pBin = new u8[static_cast(nFileSize)]; - fread(pBin, 1, static_cast(nFileSize), m_fpBflim); - fclose(m_fpBflim); - SBflimHeader* pBflimHeader = reinterpret_cast(pBin + nFileSize - (sizeof(SBflimHeader) + sizeof(SImageBlock))); - SImageBlock* pImageBlock = reinterpret_cast(pBin + nFileSize - sizeof(SImageBlock)); + fseek(fp, 0, SEEK_END); + u32 uBflimSize = ftell(fp); + fseek(fp, 0, SEEK_SET); + u8* pBflim = new u8[uBflimSize]; + fread(pBflim, 1, uBflimSize, fp); + fclose(fp); + SBflimHeader* pBflimHeader = reinterpret_cast(pBflim + uBflimSize - (sizeof(SBflimHeader) + sizeof(SImageBlock))); + SImageBlock* pImageBlock = reinterpret_cast(pBflim + uBflimSize - sizeof(SImageBlock)); do { - if (pImageBlock->Alignment != 0x80) - { - printf("ERROR: unknown alignment %04X", pImageBlock->Alignment); - bResult = false; - break; - } - if (pImageBlock->Rotate != 4 && pImageBlock->Rotate != 8) + if (pImageBlock->Format < kTextureFormatL8 || (pImageBlock->Format > kTextureFormatA4 && pImageBlock->Format < kTextureFormatL4_another) || pImageBlock->Format > kTextureFormatA4_another) { - printf("ERROR: unknown rotate %d", pImageBlock->Rotate); - bResult = false; - break; - } - if (pImageBlock->Format < kTextureFormatL8 || (pImageBlock->Format > kTextureFormatETC1_A4 && pImageBlock->Format < kTextureFormatL4) || pImageBlock->Format > kTextureFormatA4) - { - printf("ERROR: unknown format %d\n\n", pImageBlock->Format); bResult = false; + UPrintf(USTR("ERROR: unknown format %d\n\n"), pImageBlock->Format); break; } n32 nWidth = getBoundSize(pImageBlock->Width); @@ -192,68 +165,68 @@ bool CBflim::EncodeFile() n32 nCheckSize = nWidth * nHeight * s_nBPP[pImageBlock->Format] / 8; if (pImageBlock->ImageSize != nCheckSize && m_bVerbose) { - printf("INFO: width: %X(%X), height: %X(%X), checksize: %X, size: %X, bpp: %d, format: %0X\n", nWidth, pImageBlock->Width, nHeight, pImageBlock->Height, nCheckSize, pImageBlock->ImageSize, pImageBlock->ImageSize * 8 / nWidth / nHeight, pImageBlock->Format); + UPrintf(USTR("INFO: width: %X(%X), height: %X(%X), checksize: %X, size: %X, bpp: %d, format: %0X\n"), nWidth, pImageBlock->Width, nHeight, pImageBlock->Height, nCheckSize, pImageBlock->ImageSize, pImageBlock->ImageSize * 8 / nWidth / nHeight, pImageBlock->Format); } - FILE* fp = Fopen(m_pPngName, "rb"); + fp = UFopen(m_sPngName.c_str(), USTR("rb")); if (fp == nullptr) { bResult = false; break; } - png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)nullptr, nullptr, nullptr); - if (png_ptr == nullptr) + png_structp pPng = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); + if (pPng == nullptr) { fclose(fp); - printf("ERROR: png_create_read_struct error\n\n"); bResult = false; + UPrintf(USTR("ERROR: png_create_read_struct error\n\n")); break; } - png_infop info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == nullptr) + png_infop pInfo = png_create_info_struct(pPng); + if (pInfo == nullptr) { - png_destroy_read_struct(&png_ptr, (png_infopp)nullptr, (png_infopp)nullptr); + png_destroy_read_struct(&pPng, nullptr, nullptr); fclose(fp); - printf("ERROR: png_create_info_struct error\n\n"); bResult = false; + UPrintf(USTR("ERROR: png_create_info_struct error\n\n")); break; } - png_infop end_info = png_create_info_struct(png_ptr); - if (end_info == nullptr) + png_infop pEndInfo = png_create_info_struct(pPng); + if (pEndInfo == nullptr) { - png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)nullptr); + png_destroy_read_struct(&pPng, &pInfo, nullptr); fclose(fp); - printf("ERROR: png_create_info_struct error\n\n"); bResult = false; + UPrintf(USTR("ERROR: png_create_info_struct error\n\n")); break; } - if (setjmp(png_jmpbuf(png_ptr)) != 0) + if (setjmp(png_jmpbuf(pPng)) != 0) { - png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + png_destroy_read_struct(&pPng, &pInfo, &pEndInfo); fclose(fp); - printf("ERROR: setjmp error\n\n"); bResult = false; + UPrintf(USTR("ERROR: setjmp error\n\n")); break; } - png_init_io(png_ptr, fp); - png_read_info(png_ptr, info_ptr); - n32 nPngWidth = png_get_image_width(png_ptr, info_ptr); - n32 nPngHeight = png_get_image_height(png_ptr, info_ptr); - n32 nBitDepth = png_get_bit_depth(png_ptr, info_ptr); + png_init_io(pPng, fp); + png_read_info(pPng, pInfo); + n32 nPngWidth = png_get_image_width(pPng, pInfo); + n32 nPngHeight = png_get_image_height(pPng, pInfo); + n32 nBitDepth = png_get_bit_depth(pPng, pInfo); if (nBitDepth != 8) { - png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)nullptr); + png_destroy_read_struct(&pPng, &pInfo, &pEndInfo); fclose(fp); - printf("ERROR: nBitDepth != 8\n\n"); bResult = false; + UPrintf(USTR("ERROR: nBitDepth != 8\n\n")); break; } - n32 nColorType = png_get_color_type(png_ptr, info_ptr); + n32 nColorType = png_get_color_type(pPng, pInfo); if (nColorType != PNG_COLOR_TYPE_RGB_ALPHA) { - png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)nullptr); + png_destroy_read_struct(&pPng, &pInfo, &pEndInfo); fclose(fp); - printf("ERROR: nColorType != PNG_COLOR_TYPE_RGB_ALPHA\n\n"); bResult = false; + UPrintf(USTR("ERROR: nColorType != PNG_COLOR_TYPE_RGB_ALPHA\n\n")); break; } nWidth = getBoundSize(nPngWidth); @@ -264,8 +237,8 @@ bool CBflim::EncodeFile() { pRowPointers[i] = pData + i * nWidth * 4; } - png_read_image(png_ptr, pRowPointers); - png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + png_read_image(pPng, pRowPointers); + png_destroy_read_struct(&pPng, &pInfo, &pEndInfo); for (n32 i = 0; i < nPngHeight; i++) { for (n32 j = nPngWidth; j < nWidth; j++) @@ -281,7 +254,7 @@ bool CBflim::EncodeFile() fclose(fp); pvrtexture::CPVRTexture* pPVRTexture = nullptr; bool bSame = false; - if (pImageBlock->Width == nPngWidth && pImageBlock->Height == nPngHeight && decode(pBin, nWidth, nHeight, pImageBlock->Format, pImageBlock->Rotate, &pPVRTexture) == 0) + if (pImageBlock->Width == nPngWidth && pImageBlock->Height == nPngHeight && decode(pBflim, nWidth, nHeight, pImageBlock->Format, pImageBlock->Flag, &pPVRTexture) == 0) { u8* pTextureData = static_cast(pPVRTexture->getDataPtr()); bSame = true; @@ -297,20 +270,28 @@ bool CBflim::EncodeFile() delete pPVRTexture; if (!bSame) { - m_fpBflim = Fopen(m_pFileName, "wb"); - if (m_fpBflim != nullptr) + fp = UFopen(m_sFileName.c_str(), USTR("wb")); + if (fp != nullptr) { u8* pBuffer = nullptr; - encode(pData, nWidth, nHeight, pImageBlock->Format, pImageBlock->Rotate, 1, s_nBPP[pImageBlock->Format], &pBuffer); + if (encode(pData, nWidth, nHeight, pImageBlock->Format, pImageBlock->Flag, 1, s_nBPP[pImageBlock->Format], &pBuffer) != 0) + { + delete[] pBuffer; + fclose(fp); + delete[] pData; + bResult = false; + UPrintf(USTR("ERROR: encode error\n\n")); + break; + } pImageBlock->Width = nPngWidth; pImageBlock->Height = nPngHeight; pImageBlock->ImageSize = nWidth * nHeight * s_nBPP[pImageBlock->Format] / 8; pBflimHeader->FileSize = pImageBlock->ImageSize + sizeof(*pBflimHeader) + sizeof(*pImageBlock); - fwrite(pBuffer, 1, pImageBlock->ImageSize, m_fpBflim); + fwrite(pBuffer, 1, pImageBlock->ImageSize, fp); + delete[] pBuffer; fwrite(pBflimHeader, sizeof(*pBflimHeader), 1, fp); fwrite(pImageBlock, sizeof(*pImageBlock), 1, fp); - delete[] pBuffer; - fclose(m_fpBflim); + fclose(fp); } else { @@ -319,24 +300,24 @@ bool CBflim::EncodeFile() } delete[] pData; } while (false); - delete[] pBin; + delete[] pBflim; return bResult; } -bool CBflim::IsBflimFile(const char* a_pFileName) +bool CBflim::IsBflimFile(const UString& a_sFileName) { - FILE* fp = Fopen(a_pFileName, "rb"); + FILE* fp = UFopen(a_sFileName.c_str(), USTR("rb")); if (fp == nullptr) { return false; } - Fseek(fp, 0, SEEK_END); - n64 nFileSize = Ftell(fp); - if (nFileSize < sizeof(SBflimHeader) + sizeof(SImageBlock)) + fseek(fp, 0, SEEK_END); + u32 uFileSize = ftell(fp); + if (uFileSize < sizeof(SBflimHeader) + sizeof(SImageBlock)) { return false; } - Fseek(fp, nFileSize - (sizeof(SBflimHeader) + sizeof(SImageBlock)), SEEK_SET); + fseek(fp, uFileSize - (sizeof(SBflimHeader) + sizeof(SImageBlock)), SEEK_SET); SBflimHeader bflimHeader; fread(&bflimHeader, sizeof(bflimHeader), 1, fp); fclose(fp); @@ -353,14 +334,22 @@ n32 CBflim::getBoundSize(n32 a_nSize) return nSize; } -int CBflim::decode(u8* a_pBuffer, n32 a_nWidth, n32 a_nHeight, n32 a_nFormat, n32 a_nRotate, pvrtexture::CPVRTexture** a_pPVRTexture) +int CBflim::decode(u8* a_pBuffer, n32 a_nWidth, n32 a_nHeight, n32 a_nFormat, n32 a_nFlag, pvrtexture::CPVRTexture** a_pPVRTexture) { n32 nWidth = a_nWidth; n32 nHeight = a_nHeight; - if (a_nRotate == 4 || a_nRotate == 8) + n32 nRotation = a_nFlag >> kImageFlagTexelRotationPos & (SDW_BIT32(kImageFlagTexelRotationLen) - 1); + switch (nRotation) { + case kTexelRotationNone: + break; + case kTexelRotationRotate: + case kTexelRotationFlipUV: nWidth = a_nHeight; nHeight = a_nWidth; + break; + default: + return 1; } u8* pRGBA = nullptr; u8* pAlpha = nullptr; @@ -502,6 +491,8 @@ int CBflim::decode(u8* a_pBuffer, n32 a_nWidth, n32 a_nHeight, n32 a_nFormat, n3 break; case kTextureFormatL4: case kTextureFormatA4: + case kTextureFormatL4_another: + case kTextureFormatA4_another: { u8* pTemp = new u8[nWidth * nHeight]; for (n32 i = 0; i < nWidth * nHeight / 64; i++) @@ -620,9 +611,11 @@ int CBflim::decode(u8* a_pBuffer, n32 a_nWidth, n32 a_nHeight, n32 a_nFormat, n3 pvrTextureHeaderV3.u64PixelFormat = pvrtexture::PixelType('l', 'a', 0, 0, 4, 4, 0, 0).PixelTypeID; break; case kTextureFormatL4: + case kTextureFormatL4_another: pvrTextureHeaderV3.u64PixelFormat = pvrtexture::PixelType('l', 0, 0, 0, 8, 0, 0, 0).PixelTypeID; break; case kTextureFormatA4: + case kTextureFormatA4_another: pvrTextureHeaderV3.u64PixelFormat = pvrtexture::PixelType('a', 0, 0, 0, 8, 0, 0, 0).PixelTypeID; break; case kTextureFormatETC1: @@ -658,11 +651,11 @@ int CBflim::decode(u8* a_pBuffer, n32 a_nWidth, n32 a_nHeight, n32 a_nFormat, n3 } delete[] pAlpha; } - if (a_nRotate == 4) + if (nRotation == kTexelRotationRotate) { pvrtexture::Rotate90(**a_pPVRTexture, ePVRTAxisZ, false); } - else if (a_nRotate == 8) + else if (nRotation == kTexelRotationFlipUV) { pvrtexture::Rotate90(**a_pPVRTexture, ePVRTAxisZ, true); pvrtexture::Flip(**a_pPVRTexture, ePVRTAxisX); @@ -670,7 +663,7 @@ int CBflim::decode(u8* a_pBuffer, n32 a_nWidth, n32 a_nHeight, n32 a_nFormat, n3 return 0; } -void CBflim::encode(u8* a_pData, n32 a_nWidth, n32 a_nHeight, n32 a_nFormat, n32 a_nRotate, n32 a_nMipmapLevel, n32 a_nBPP, u8** a_pBuffer) +int CBflim::encode(u8* a_pData, n32 a_nWidth, n32 a_nHeight, n32 a_nFormat, n32 a_nFlag, n32 a_nMipmapLevel, n32 a_nBPP, u8** a_pBuffer) { PVRTextureHeaderV3 pvrTextureHeaderV3; pvrTextureHeaderV3.u64PixelFormat = pvrtexture::PVRStandard8PixelType.PixelTypeID; @@ -711,12 +704,20 @@ void CBflim::encode(u8* a_pData, n32 a_nWidth, n32 a_nHeight, n32 a_nFormat, n32 } n32 nWidth = a_nWidth; n32 nHeight = a_nHeight; - if (a_nRotate == 4 || a_nRotate == 8) + n32 nRotation = a_nFlag >> kImageFlagTexelRotationPos & (SDW_BIT32(kImageFlagTexelRotationLen) - 1); + switch (nRotation) { + case kTexelRotationNone: + break; + case kTexelRotationRotate: + case kTexelRotationFlipUV: nWidth = a_nHeight; nHeight = a_nWidth; + break; + default: + return 1; } - if (a_nRotate == 4) + if (nRotation == kTexelRotationRotate) { pvrtexture::Rotate90(*pPVRTexture, ePVRTAxisZ, true); if (a_nFormat == kTextureFormatETC1_A4) @@ -724,7 +725,7 @@ void CBflim::encode(u8* a_pData, n32 a_nWidth, n32 a_nHeight, n32 a_nFormat, n32 pvrtexture::Rotate90(*pPVRTextureAlpha, ePVRTAxisZ, true); } } - else if (a_nRotate == 8) + else if (nRotation == kTexelRotationFlipUV) { pvrtexture::Flip(*pPVRTexture, ePVRTAxisX); pvrtexture::Rotate90(*pPVRTexture, ePVRTAxisZ, false); @@ -777,9 +778,11 @@ void CBflim::encode(u8* a_pData, n32 a_nWidth, n32 a_nHeight, n32 a_nFormat, n32 uPixelFormat = pvrtexture::PixelType('l', 'a', 0, 0, 4, 4, 0, 0).PixelTypeID; break; case kTextureFormatL4: + case kTextureFormatL4_another: uPixelFormat = pvrtexture::PixelType('l', 0, 0, 0, 8, 0, 0, 0).PixelTypeID; break; case kTextureFormatA4: + case kTextureFormatA4_another: uPixelFormat = pvrtexture::PixelType('a', 0, 0, 0, 8, 0, 0, 0).PixelTypeID; break; case kTextureFormatETC1: @@ -951,6 +954,8 @@ void CBflim::encode(u8* a_pData, n32 a_nWidth, n32 a_nHeight, n32 a_nFormat, n32 break; case kTextureFormatL4: case kTextureFormatA4: + case kTextureFormatL4_another: + case kTextureFormatA4_another: { u8* pTemp = new u8[nMipmapWidth * nMipmapHeight]; for (n32 i = 0; i < nMipmapHeight; i++) @@ -1038,4 +1043,5 @@ void CBflim::encode(u8* a_pData, n32 a_nWidth, n32 a_nHeight, n32 a_nFormat, n32 { delete pPVRTextureAlpha; } + return 0; } diff --git a/src/bflim.h b/src/bflim.h index 50214fd..124b720 100644 --- a/src/bflim.h +++ b/src/bflim.h @@ -28,7 +28,7 @@ struct SImageBlock u16 Height; u16 Alignment; u8 Format; - u8 Rotate; + u8 Flag; u32 ImageSize; } SDW_GNUC_PACKED; #include SDW_MSC_POP_PACKED @@ -52,29 +52,39 @@ class CBflim kTextureFormatETC1_A4 = 11, kTextureFormatL4 = 12, kTextureFormatA4 = 13, - kTextureFormatL4_another = 0x12, - kTextureFormatA4_another = 0x13 + kTextureFormatL4_another = 18, + kTextureFormatA4_another = 19 + }; + enum ETexelRotation + { + kTexelRotationNone, + kTexelRotationRotate, + kTexelRotationFlipUV + }; + enum EImageFlag + { + kImageFlagTexelRotationPos = 2, + kImageFlagTexelRotationLen = 2 }; CBflim(); ~CBflim(); - void SetFileName(const char* a_pFileName); - void SetPngName(const char* a_pPngName); + void SetFileName(const UString& a_sFileName); + void SetPngName(const UString& a_sPngName); void SetVerbose(bool a_bVerbose); bool DecodeFile(); bool EncodeFile(); - static bool IsBflimFile(const char* a_pFileName); + static bool IsBflimFile(const UString& a_sFileName); static const u32 s_uSignatureBflim; static const u32 s_uSignatureImage; static const int s_nBPP[]; static const int s_nDecodeTransByte[64]; private: static n32 getBoundSize(n32 a_nSize); - static int decode(u8* a_pBuffer, n32 a_nWidth, n32 a_nHeight, n32 a_nFormat, n32 a_nRotate, pvrtexture::CPVRTexture** a_pPVRTexture); - static void encode(u8* a_pData, n32 a_nWidth, n32 a_nHeight, n32 a_nFormat, n32 a_nRotate, n32 a_nMipmapLevel, n32 a_nBPP, u8** a_pBuffer); - const char* m_pFileName; - const char* m_pPngName; + static int decode(u8* a_pBuffer, n32 a_nWidth, n32 a_nHeight, n32 a_nFormat, n32 a_nFlag, pvrtexture::CPVRTexture** a_pPVRTexture); + static int encode(u8* a_pData, n32 a_nWidth, n32 a_nHeight, n32 a_nFormat, n32 a_nFlag, n32 a_nMipmapLevel, n32 a_nBPP, u8** a_pBuffer); + UString m_sFileName; + UString m_sPngName; bool m_bVerbose; - FILE* m_fpBflim; }; #endif // BFLIM_H_ diff --git a/src/bflimtool.cpp b/src/bflimtool.cpp index 87b1f04..61fd73a 100644 --- a/src/bflimtool.cpp +++ b/src/bflimtool.cpp @@ -3,19 +3,17 @@ CBflimTool::SOption CBflimTool::s_Option[] = { - { "decode", 'd', "decode the bflim file" }, - { "encode", 'e', "encode the bflim file" }, - { "file", 'f', "the bflim file" }, - { "png", 'p', "the png file for the bflim file" }, - { "verbose", 'v', "show the info" }, - { "help", 'h', "show this help" }, + { USTR("decode"), USTR('d'), USTR("decode the target file") }, + { USTR("encode"), USTR('e'), USTR("encode the target file") }, + { USTR("file"), USTR('f'), USTR("the target file") }, + { USTR("png"), USTR('p'), USTR("the png file for the target file") }, + { USTR("verbose"), USTR('v'), USTR("show the info") }, + { USTR("help"), USTR('h'), USTR("show this help") }, { nullptr, 0, nullptr } }; CBflimTool::CBflimTool() : m_eAction(kActionNone) - , m_pFileName(nullptr) - , m_pPngName(nullptr) , m_bVerbose(false) { } @@ -24,7 +22,7 @@ CBflimTool::~CBflimTool() { } -int CBflimTool::ParseOptions(int a_nArgc, char* a_pArgv[]) +int CBflimTool::ParseOptions(int a_nArgc, UChar* a_pArgv[]) { if (a_nArgc <= 1) { @@ -32,18 +30,18 @@ int CBflimTool::ParseOptions(int a_nArgc, char* a_pArgv[]) } for (int i = 1; i < a_nArgc; i++) { - int nArgpc = static_cast(strlen(a_pArgv[i])); + int nArgpc = static_cast(UCslen(a_pArgv[i])); if (nArgpc == 0) { continue; } int nIndex = i; - if (a_pArgv[i][0] != '-') + if (a_pArgv[i][0] != USTR('-')) { - printf("ERROR: illegal option\n\n"); + UPrintf(USTR("ERROR: illegal option\n\n")); return 1; } - else if (nArgpc > 1 && a_pArgv[i][1] != '-') + else if (nArgpc > 1 && a_pArgv[i][1] != USTR('-')) { for (int j = 1; j < nArgpc; j++) { @@ -52,31 +50,31 @@ int CBflimTool::ParseOptions(int a_nArgc, char* a_pArgv[]) case kParseOptionReturnSuccess: break; case kParseOptionReturnIllegalOption: - printf("ERROR: illegal option\n\n"); + UPrintf(USTR("ERROR: illegal option\n\n")); return 1; case kParseOptionReturnNoArgument: - printf("ERROR: no argument\n\n"); + UPrintf(USTR("ERROR: no argument\n\n")); return 1; case kParseOptionReturnOptionConflict: - printf("ERROR: option conflict\n\n"); + UPrintf(USTR("ERROR: option conflict\n\n")); return 1; } } } - else if (nArgpc > 2 && a_pArgv[i][1] == '-') + else if (nArgpc > 2 && a_pArgv[i][1] == USTR('-')) { switch (parseOptions(a_pArgv[i] + 2, nIndex, a_nArgc, a_pArgv)) { case kParseOptionReturnSuccess: break; case kParseOptionReturnIllegalOption: - printf("ERROR: illegal option\n\n"); + UPrintf(USTR("ERROR: illegal option\n\n")); return 1; case kParseOptionReturnNoArgument: - printf("ERROR: no argument\n\n"); + UPrintf(USTR("ERROR: no argument\n\n")); return 1; case kParseOptionReturnOptionConflict: - printf("ERROR: option conflict\n\n"); + UPrintf(USTR("ERROR: option conflict\n\n")); return 1; } } @@ -89,27 +87,24 @@ int CBflimTool::CheckOptions() { if (m_eAction == kActionNone) { - printf("ERROR: nothing to do\n\n"); + UPrintf(USTR("ERROR: nothing to do\n\n")); return 1; } if (m_eAction != kActionHelp) { - if (m_pFileName == nullptr) + if (m_sFileName.empty()) { - printf("ERROR: no --file option\n\n"); + UPrintf(USTR("ERROR: no --file option\n\n")); return 1; } - if (m_pPngName == nullptr) + if (m_sPngName.empty()) { - printf("ERROR: no --png option\n\n"); + UPrintf(USTR("ERROR: no --png option\n\n")); return 1; } - } - if (m_eAction == kActionDecode || m_eAction == kActionEncode) - { - if (!CBflim::IsBflimFile(m_pFileName)) + if (!CBflim::IsBflimFile(m_sFileName)) { - printf("ERROR: %s is not a bflim file\n\n", m_pFileName); + UPrintf(USTR("ERROR: %") PRIUS USTR(" is not a bflim file\n\n"), m_sFileName.c_str()); return 1; } } @@ -118,38 +113,38 @@ int CBflimTool::CheckOptions() int CBflimTool::Help() { - printf("bflimtool %s by dnasdw\n\n", BFLIMTOOL_VERSION); - printf("usage: bflimtool [option...] [option]...\n"); - printf("sample:\n"); - printf(" bflimtool -dvfp title.bflim title.png\n"); - printf(" bflimtool -evfp title.bflim title_new.png\n"); - printf("\n"); - printf("option:\n"); + UPrintf(USTR("bflimtool %") PRIUS USTR(" by dnasdw\n\n"), AToU(BFLIMTOOL_VERSION).c_str()); + UPrintf(USTR("usage: bflimtool [option...] [option]...\n")); + UPrintf(USTR("sample:\n")); + UPrintf(USTR(" bflimtool -dvfp title.bflim title.png\n")); + UPrintf(USTR(" bflimtool -evfp title.bflim title_new.png\n")); + UPrintf(USTR("\n")); + UPrintf(USTR("option:\n")); SOption* pOption = s_Option; while (pOption->Name != nullptr || pOption->Doc != nullptr) { if (pOption->Name != nullptr) { - printf(" "); + UPrintf(USTR(" ")); if (pOption->Key != 0) { - printf("-%c,", pOption->Key); + UPrintf(USTR("-%c,"), pOption->Key); } else { - printf(" "); + UPrintf(USTR(" ")); } - printf(" --%-8s", pOption->Name); - if (strlen(pOption->Name) >= 8 && pOption->Doc != nullptr) + UPrintf(USTR(" --%-8") PRIUS, pOption->Name); + if (UCslen(pOption->Name) >= 8 && pOption->Doc != nullptr) { - printf("\n%16s", ""); + UPrintf(USTR("\n%16") PRIUS, USTR("")); } } if (pOption->Doc != nullptr) { - printf("%s", pOption->Doc); + UPrintf(USTR("%") PRIUS, pOption->Doc); } - printf("\n"); + UPrintf(USTR("\n")); pOption++; } return 0; @@ -161,7 +156,7 @@ int CBflimTool::Action() { if (!decodeFile()) { - printf("ERROR: decode file failed\n\n"); + UPrintf(USTR("ERROR: decode file failed\n\n")); return 1; } } @@ -169,7 +164,7 @@ int CBflimTool::Action() { if (!encodeFile()) { - printf("ERROR: encode file failed\n\n"); + UPrintf(USTR("ERROR: encode file failed\n\n")); return 1; } } @@ -180,9 +175,9 @@ int CBflimTool::Action() return 0; } -CBflimTool::EParseOptionReturn CBflimTool::parseOptions(const char* a_pName, int& a_nIndex, int a_nArgc, char* a_pArgv[]) +CBflimTool::EParseOptionReturn CBflimTool::parseOptions(const UChar* a_pName, int& a_nIndex, int a_nArgc, UChar* a_pArgv[]) { - if (strcmp(a_pName, "decode") == 0) + if (UCscmp(a_pName, USTR("decode")) == 0) { if (m_eAction == kActionNone) { @@ -193,7 +188,7 @@ CBflimTool::EParseOptionReturn CBflimTool::parseOptions(const char* a_pName, int return kParseOptionReturnOptionConflict; } } - else if (strcmp(a_pName, "encode") == 0) + else if (UCscmp(a_pName, USTR("encode")) == 0) { if (m_eAction == kActionNone) { @@ -204,34 +199,34 @@ CBflimTool::EParseOptionReturn CBflimTool::parseOptions(const char* a_pName, int return kParseOptionReturnOptionConflict; } } - else if (strcmp(a_pName, "file") == 0) + else if (UCscmp(a_pName, USTR("file")) == 0) { if (a_nIndex + 1 >= a_nArgc) { return kParseOptionReturnNoArgument; } - m_pFileName = a_pArgv[++a_nIndex]; + m_sFileName = a_pArgv[++a_nIndex]; } - else if (strcmp(a_pName, "png") == 0) + else if (UCscmp(a_pName, USTR("png")) == 0) { if (a_nIndex + 1 >= a_nArgc) { return kParseOptionReturnNoArgument; } - m_pPngName = a_pArgv[++a_nIndex]; + m_sPngName = a_pArgv[++a_nIndex]; } - else if (strcmp(a_pName, "verbose") == 0) + else if (UCscmp(a_pName, USTR("verbose")) == 0) { m_bVerbose = true; } - else if (strcmp(a_pName, "help") == 0) + else if (UCscmp(a_pName, USTR("help")) == 0) { m_eAction = kActionHelp; } return kParseOptionReturnSuccess; } -CBflimTool::EParseOptionReturn CBflimTool::parseOptions(int a_nKey, int& a_nIndex, int m_nArgc, char* a_pArgv[]) +CBflimTool::EParseOptionReturn CBflimTool::parseOptions(int a_nKey, int& a_nIndex, int m_nArgc, UChar* a_pArgv[]) { for (SOption* pOption = s_Option; pOption->Name != nullptr || pOption->Key != 0 || pOption->Doc != nullptr; pOption++) { @@ -246,8 +241,8 @@ CBflimTool::EParseOptionReturn CBflimTool::parseOptions(int a_nKey, int& a_nInde bool CBflimTool::decodeFile() { CBflim bflim; - bflim.SetFileName(m_pFileName); - bflim.SetPngName(m_pPngName); + bflim.SetFileName(m_sFileName); + bflim.SetPngName(m_sPngName); bflim.SetVerbose(m_bVerbose); return bflim.DecodeFile(); } @@ -255,15 +250,14 @@ bool CBflimTool::decodeFile() bool CBflimTool::encodeFile() { CBflim bflim; - bflim.SetFileName(m_pFileName); - bflim.SetPngName(m_pPngName); + bflim.SetFileName(m_sFileName); + bflim.SetPngName(m_sPngName); bflim.SetVerbose(m_bVerbose); return bflim.EncodeFile(); } -int main(int argc, char* argv[]) +int UMain(int argc, UChar* argv[]) { - SetLocale(); CBflimTool tool; if (tool.ParseOptions(argc, argv) != 0) { diff --git a/src/bflimtool.h b/src/bflimtool.h index 80ee9eb..83eddcd 100644 --- a/src/bflimtool.h +++ b/src/bflimtool.h @@ -22,25 +22,25 @@ class CBflimTool }; struct SOption { - const char* Name; + const UChar* Name; int Key; - const char* Doc; + const UChar* Doc; }; CBflimTool(); ~CBflimTool(); - int ParseOptions(int a_nArgc, char* a_pArgv[]); + int ParseOptions(int a_nArgc, UChar* a_pArgv[]); int CheckOptions(); int Help(); int Action(); static SOption s_Option[]; private: - EParseOptionReturn parseOptions(const char* a_pName, int& a_nIndex, int a_nArgc, char* a_pArgv[]); - EParseOptionReturn parseOptions(int a_nKey, int& a_nIndex, int a_nArgc, char* a_pArgv[]); + EParseOptionReturn parseOptions(const UChar* a_pName, int& a_nIndex, int a_nArgc, UChar* a_pArgv[]); + EParseOptionReturn parseOptions(int a_nKey, int& a_nIndex, int a_nArgc, UChar* a_pArgv[]); bool decodeFile(); bool encodeFile(); EAction m_eAction; - const char* m_pFileName; - const char* m_pPngName; + UString m_sFileName; + UString m_sPngName; bool m_bVerbose; };