mirror of https://github.com/AxioDL/metaforce.git
Prelim release badging
This commit is contained in:
parent
a271b6ab58
commit
f6514b2575
|
@ -111,12 +111,16 @@ find_package(Git)
|
||||||
if(GIT_FOUND)
|
if(GIT_FOUND)
|
||||||
message(STATUS "Found GIT: ${GIT_EXECUTABLE}")
|
message(STATUS "Found GIT: ${GIT_EXECUTABLE}")
|
||||||
# Get the current working branch
|
# Get the current working branch
|
||||||
execute_process(COMMAND "${GIT_EXECUTABLE}" rev-parse --abbrev-ref HEAD WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" OUTPUT_VARIABLE GIT_BRANCH OUTPUT_STRIP_TRAILING_WHITESPACE )
|
execute_process(COMMAND "${GIT_EXECUTABLE}" rev-parse --abbrev-ref HEAD WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||||
|
OUTPUT_VARIABLE GIT_BRANCH OUTPUT_STRIP_TRAILING_WHITESPACE )
|
||||||
|
|
||||||
# Get the latest abbreviated commit hash of the working branch
|
# Get the latest abbreviated commit hash of the working branch
|
||||||
execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --format=%h WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE GIT_COMMIT_HASH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --format=%h WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE
|
||||||
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse HEAD WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE GIT_COMMIT_HASH_FULL OUTPUT_STRIP_TRAILING_WHITESPACE)
|
GIT_COMMIT_HASH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --format=%ad WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE GIT_COMMIT_DATE OUTPUT_STRIP_TRAILING_WHITESPACE)
|
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse HEAD WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE
|
||||||
|
GIT_COMMIT_HASH_FULL OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --format=%ad WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE
|
||||||
|
GIT_COMMIT_DATE OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
else()
|
else()
|
||||||
message(STATUS "Unable to find GIT, commit information will not be available")
|
message(STATUS "Unable to find GIT, commit information will not be available")
|
||||||
set(GIT_BRANCH "")
|
set(GIT_BRANCH "")
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/DataSpec ${CMAKE_SOURCE_DIR}/Runtime)
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/DataSpec ${CMAKE_SOURCE_DIR}/Runtime)
|
||||||
add_subdirectory(locale)
|
add_subdirectory(locale)
|
||||||
add_subdirectory(icons)
|
add_subdirectory(icons)
|
||||||
|
add_subdirectory(badging)
|
||||||
|
|
||||||
atdna(atdna_Space.cpp Space.hpp)
|
atdna(atdna_Space.cpp Space.hpp)
|
||||||
atdna(atdna_ResourceBrowser.cpp ResourceBrowser.hpp)
|
atdna(atdna_ResourceBrowser.cpp ResourceBrowser.hpp)
|
||||||
|
@ -36,6 +37,7 @@ add_executable(urde WIN32 MACOSX_BUNDLE
|
||||||
target_link_libraries(urde
|
target_link_libraries(urde
|
||||||
UrdeLocales
|
UrdeLocales
|
||||||
UrdeIcons
|
UrdeIcons
|
||||||
|
UrdeBadging
|
||||||
RuntimeCommon
|
RuntimeCommon
|
||||||
DNAMP3 DNAMP2 DNAMP1
|
DNAMP3 DNAMP2 DNAMP1
|
||||||
DNACommon specter specter-fonts freetype ${DATA_SPEC_LIBS}
|
DNACommon specter specter-fonts freetype ${DATA_SPEC_LIBS}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "SplashScreen.hpp"
|
#include "SplashScreen.hpp"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
#include "badging/Badging.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -17,6 +18,10 @@ namespace urde
|
||||||
#define LINE_WIDTH 2
|
#define LINE_WIDTH 2
|
||||||
#define TEXT_MARGIN 10
|
#define TEXT_MARGIN 10
|
||||||
|
|
||||||
|
#define BADGE_WIDTH 551
|
||||||
|
#define BADGE_HEIGHT 217
|
||||||
|
#define BADGE_MARGIN 35
|
||||||
|
|
||||||
SplashScreen::SplashScreen(ViewManager& vm, specter::ViewResources& res)
|
SplashScreen::SplashScreen(ViewManager& vm, specter::ViewResources& res)
|
||||||
: ModalWindow(res, vm.rootView(),
|
: ModalWindow(res, vm.rootView(),
|
||||||
specter::RectangleConstraint(SPLASH_WIDTH * res.pixelFactor(),
|
specter::RectangleConstraint(SPLASH_WIDTH * res.pixelFactor(),
|
||||||
|
@ -95,6 +100,10 @@ void SplashScreen::updateContentOpacity(float opacity)
|
||||||
m_buildInfo.reset(new specter::MultiLineTextView(res, *this, res.m_mainFont, specter::TextView::Alignment::Right));
|
m_buildInfo.reset(new specter::MultiLineTextView(res, *this, res.m_mainFont, specter::TextView::Alignment::Right));
|
||||||
m_buildInfo->typesetGlyphs(m_buildInfoStr, clearColor);
|
m_buildInfo->typesetGlyphs(m_buildInfoStr, clearColor);
|
||||||
|
|
||||||
|
m_badgeIcon.reset(new specter::IconView(res, *this, GetBadge()));
|
||||||
|
m_badgeText.reset(new specter::TextView(res, *this, res.m_heading18, specter::TextView::Alignment::Right));
|
||||||
|
m_badgeText->typesetGlyphs(BADGE_PHRASE, clearColor);
|
||||||
|
|
||||||
m_newButt.m_view.reset(new specter::Button(res, *this, &m_newProjBind, m_newString,
|
m_newButt.m_view.reset(new specter::Button(res, *this, &m_newProjBind, m_newString,
|
||||||
nullptr, specter::Button::Style::Text));
|
nullptr, specter::Button::Style::Text));
|
||||||
m_openButt.m_view.reset(new specter::Button(res, *this, &m_openProjBind, m_openString,
|
m_openButt.m_view.reset(new specter::Button(res, *this, &m_openProjBind, m_openString,
|
||||||
|
@ -110,6 +119,8 @@ void SplashScreen::updateContentOpacity(float opacity)
|
||||||
zeus::CColor color = zeus::CColor::lerp(clearColor, res.themeData().uiText(), opacity);
|
zeus::CColor color = zeus::CColor::lerp(clearColor, res.themeData().uiText(), opacity);
|
||||||
m_title->colorGlyphs(color);
|
m_title->colorGlyphs(color);
|
||||||
m_buildInfo->colorGlyphs(color);
|
m_buildInfo->colorGlyphs(color);
|
||||||
|
m_badgeIcon->setMultiplyColor({1.f, 1.f, 1.f, color.a});
|
||||||
|
m_badgeText->colorGlyphs(color);
|
||||||
m_newButt.m_view->colorGlyphs(color);
|
m_newButt.m_view->colorGlyphs(color);
|
||||||
m_openButt.m_view->colorGlyphs(color);
|
m_openButt.m_view->colorGlyphs(color);
|
||||||
m_extractButt.m_view->colorGlyphs(color);
|
m_extractButt.m_view->colorGlyphs(color);
|
||||||
|
@ -226,6 +237,12 @@ void SplashScreen::resized(const boo::SWindowRect& root, const boo::SWindowRect&
|
||||||
centerRect.location[0] = root.size[0] / 2 - (SPLASH_WIDTH * pf / 2.0);
|
centerRect.location[0] = root.size[0] / 2 - (SPLASH_WIDTH * pf / 2.0);
|
||||||
centerRect.location[1] = root.size[1] / 2 - (SPLASH_HEIGHT * pf / 2.0);
|
centerRect.location[1] = root.size[1] / 2 - (SPLASH_HEIGHT * pf / 2.0);
|
||||||
|
|
||||||
|
boo::SWindowRect badgeRect = centerRect;
|
||||||
|
badgeRect.location[0] += LINE_WIDTH * pf;
|
||||||
|
badgeRect.location[1] += BADGE_MARGIN * pf;
|
||||||
|
badgeRect.size[0] = BADGE_WIDTH;
|
||||||
|
badgeRect.size[1] = BADGE_HEIGHT;
|
||||||
|
|
||||||
boo::SWindowRect textRect = centerRect;
|
boo::SWindowRect textRect = centerRect;
|
||||||
textRect.location[0] += TEXT_MARGIN * pf;
|
textRect.location[0] += TEXT_MARGIN * pf;
|
||||||
textRect.location[1] += (SPLASH_HEIGHT - 36) * pf;
|
textRect.location[1] += (SPLASH_HEIGHT - 36) * pf;
|
||||||
|
@ -236,6 +253,11 @@ void SplashScreen::resized(const boo::SWindowRect& root, const boo::SWindowRect&
|
||||||
textRect.location[1] -= 5 * pf;
|
textRect.location[1] -= 5 * pf;
|
||||||
m_buildInfo->resized(root, textRect);
|
m_buildInfo->resized(root, textRect);
|
||||||
|
|
||||||
|
textRect.location[0] = centerRect.location[0] + (SPLASH_WIDTH - TEXT_MARGIN) * pf;
|
||||||
|
textRect.location[1] = centerRect.location[1] + (BADGE_MARGIN + TEXT_MARGIN) * pf;
|
||||||
|
m_badgeIcon->resized(root, badgeRect);
|
||||||
|
m_badgeText->resized(root, textRect);
|
||||||
|
|
||||||
textRect.size[0] = m_newButt.m_view->nominalWidth();
|
textRect.size[0] = m_newButt.m_view->nominalWidth();
|
||||||
textRect.size[1] = m_newButt.m_view->nominalHeight();
|
textRect.size[1] = m_newButt.m_view->nominalHeight();
|
||||||
textRect.location[1] = centerRect.location[1] + 20 * pf;
|
textRect.location[1] = centerRect.location[1] + 20 * pf;
|
||||||
|
@ -269,6 +291,8 @@ void SplashScreen::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||||
{
|
{
|
||||||
m_title->draw(gfxQ);
|
m_title->draw(gfxQ);
|
||||||
m_buildInfo->draw(gfxQ);
|
m_buildInfo->draw(gfxQ);
|
||||||
|
m_badgeIcon->draw(gfxQ);
|
||||||
|
m_badgeText->draw(gfxQ);
|
||||||
m_newButt.m_view->draw(gfxQ);
|
m_newButt.m_view->draw(gfxQ);
|
||||||
m_openButt.m_view->draw(gfxQ);
|
m_openButt.m_view->draw(gfxQ);
|
||||||
m_extractButt.m_view->draw(gfxQ);
|
m_extractButt.m_view->draw(gfxQ);
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#include <specter/MultiLineTextView.hpp>
|
#include <specter/MultiLineTextView.hpp>
|
||||||
#include <specter/FileBrowser.hpp>
|
#include <specter/FileBrowser.hpp>
|
||||||
#include <specter/Menu.hpp>
|
#include <specter/Menu.hpp>
|
||||||
|
#include <specter/Icon.hpp>
|
||||||
|
|
||||||
#include "ViewManager.hpp"
|
#include "ViewManager.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
|
@ -22,6 +24,8 @@ class SplashScreen : public specter::ModalWindow
|
||||||
std::unique_ptr<specter::TextView> m_title;
|
std::unique_ptr<specter::TextView> m_title;
|
||||||
std::string m_buildInfoStr;
|
std::string m_buildInfoStr;
|
||||||
std::unique_ptr<specter::MultiLineTextView> m_buildInfo;
|
std::unique_ptr<specter::MultiLineTextView> m_buildInfo;
|
||||||
|
std::unique_ptr<specter::IconView> m_badgeIcon;
|
||||||
|
std::unique_ptr<specter::TextView> m_badgeText;
|
||||||
|
|
||||||
std::string m_newString;
|
std::string m_newString;
|
||||||
specter::ViewChild<std::unique_ptr<specter::Button>> m_newButt;
|
specter::ViewChild<std::unique_ptr<specter::Button>> m_newButt;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "locale/locale.hpp"
|
#include "locale/locale.hpp"
|
||||||
#include "ResourceBrowser.hpp"
|
#include "ResourceBrowser.hpp"
|
||||||
#include "icons/icons.hpp"
|
#include "icons/icons.hpp"
|
||||||
|
#include "badging/Badging.hpp"
|
||||||
#include "Runtime/Particle/CGenDescription.hpp"
|
#include "Runtime/Particle/CGenDescription.hpp"
|
||||||
#include "Runtime/Particle/CElectricDescription.hpp"
|
#include "Runtime/Particle/CElectricDescription.hpp"
|
||||||
#include "Runtime/Particle/CSwooshDescription.hpp"
|
#include "Runtime/Particle/CSwooshDescription.hpp"
|
||||||
|
@ -280,6 +281,7 @@ void ViewManager::init(boo::IApplication* app)
|
||||||
m_mainCommandQueue = m_mainWindow->getCommandQueue();
|
m_mainCommandQueue = m_mainWindow->getCommandQueue();
|
||||||
m_viewResources.init(m_mainBooFactory, &m_fontCache, &m_themeData, pixelFactor);
|
m_viewResources.init(m_mainBooFactory, &m_fontCache, &m_themeData, pixelFactor);
|
||||||
m_iconsToken = InitializeIcons(m_viewResources);
|
m_iconsToken = InitializeIcons(m_viewResources);
|
||||||
|
m_badgeToken = InitializeBadging(m_viewResources);
|
||||||
m_viewResources.prepFontCacheAsync(m_mainWindow.get());
|
m_viewResources.prepFontCacheAsync(m_mainWindow.get());
|
||||||
specter::RootView* root = SetupRootView();
|
specter::RootView* root = SetupRootView();
|
||||||
m_showSplash = true;
|
m_showSplash = true;
|
||||||
|
|
|
@ -31,6 +31,7 @@ class ViewManager : public specter::IViewManager
|
||||||
specter::DefaultThemeData m_themeData;
|
specter::DefaultThemeData m_themeData;
|
||||||
specter::ViewResources m_viewResources;
|
specter::ViewResources m_viewResources;
|
||||||
boo::GraphicsDataToken m_iconsToken;
|
boo::GraphicsDataToken m_iconsToken;
|
||||||
|
boo::GraphicsDataToken m_badgeToken;
|
||||||
specter::Translator m_translator;
|
specter::Translator m_translator;
|
||||||
std::unique_ptr<boo::IWindow> m_mainWindow;
|
std::unique_ptr<boo::IWindow> m_mainWindow;
|
||||||
boo::IGraphicsDataFactory* m_mainBooFactory = nullptr;
|
boo::IGraphicsDataFactory* m_mainBooFactory = nullptr;
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
#include "Badging.hpp"
|
||||||
|
#include "athena/MemoryReader.hpp"
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
extern "C" uint8_t URDE_BADGE[];
|
||||||
|
extern "C" size_t URDE_BADGE_SZ;
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
static logvisor::Module Log("URDE::badging");
|
||||||
|
static specter::Icon g_BadgeIcon;
|
||||||
|
|
||||||
|
boo::GraphicsDataToken InitializeBadging(specter::ViewResources& viewRes)
|
||||||
|
{
|
||||||
|
athena::io::MemoryReader r(URDE_BADGE, URDE_BADGE_SZ);
|
||||||
|
|
||||||
|
size_t fmt = r.readUint32Big();
|
||||||
|
if (fmt != 16)
|
||||||
|
Log.report(logvisor::Fatal, "incorrect icon texture format");
|
||||||
|
size_t width = r.readUint16Big();
|
||||||
|
size_t height = r.readUint16Big();
|
||||||
|
size_t mips = r.readUint32Big();
|
||||||
|
size_t decompSz = r.readUint32Big();
|
||||||
|
|
||||||
|
std::unique_ptr<uint8_t[]> texels(new uint8_t[decompSz]);
|
||||||
|
uLongf destSz = decompSz;
|
||||||
|
size_t pos = r.position();
|
||||||
|
if (uncompress(texels.get(), &destSz, URDE_BADGE + pos, URDE_BADGE_SZ - pos) != Z_OK)
|
||||||
|
Log.report(logvisor::Fatal, "unable to decompress badge");
|
||||||
|
|
||||||
|
return viewRes.m_factory->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||||
|
{
|
||||||
|
specter::IconAtlas<1, 1> atlas;
|
||||||
|
|
||||||
|
atlas.initializeAtlas(ctx.newStaticTexture(width, height, mips,
|
||||||
|
boo::TextureFormat::RGBA8,
|
||||||
|
texels.get(), destSz));
|
||||||
|
g_BadgeIcon = atlas.getIcon(0, 0);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
specter::Icon& GetBadge()
|
||||||
|
{
|
||||||
|
return g_BadgeIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef __URDE_BADGING_HPP__
|
||||||
|
#define __URDE_BADGING_HPP__
|
||||||
|
|
||||||
|
#include "specter/ViewResources.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
boo::GraphicsDataToken InitializeBadging(specter::ViewResources& viewRes);
|
||||||
|
|
||||||
|
specter::Icon& GetBadge();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef BADGE_PHRASE
|
||||||
|
#define BADGE_PHRASE "Prototype"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __URDE_BADGING_HPP__
|
|
@ -0,0 +1,16 @@
|
||||||
|
cmake_policy(SET CMP0053 OLD)
|
||||||
|
|
||||||
|
|
||||||
|
include_directories(${LIBPNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})
|
||||||
|
add_executable(packbadge packbadge.c)
|
||||||
|
target_link_libraries(packbadge ${PNG_LIB} ${ZLIB_LIBRARIES})
|
||||||
|
|
||||||
|
add_custom_command(OUTPUT badge.bin COMMAND $<TARGET_FILE:packbadge>
|
||||||
|
ARGS ${CMAKE_CURRENT_SOURCE_DIR}/badge.png
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/badge.bin
|
||||||
|
MAIN_DEPENDENCY badge.png COMMENT "Generating badge.bin")
|
||||||
|
|
||||||
|
bintoc(badge.c ${CMAKE_CURRENT_BINARY_DIR}/badge.bin URDE_BADGE)
|
||||||
|
add_library(UrdeBadging
|
||||||
|
badge.c badge.bin
|
||||||
|
Badging.hpp Badging.cpp)
|
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
|
@ -0,0 +1,174 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <zlib.h>
|
||||||
|
#include <png.h>
|
||||||
|
|
||||||
|
#if __FreeBSD__
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
#define _bswap32(v) _byteswap_ulong(v)
|
||||||
|
#define _bswap16(v) _byteswap_ushort(v)
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <Windows.h>
|
||||||
|
#else
|
||||||
|
#define _bswap32(v) __builtin_bswap32(v)
|
||||||
|
#define _bswap16(v) __builtin_bswap16(v)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc < 3)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: packbadge <in.png> <out.bin>\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate input */
|
||||||
|
FILE* fp = fopen(argv[1], "rb");
|
||||||
|
if (!fp)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "'%s' is not able to be opened for reading as a regular file\n", argv[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE* ofp = fopen(argv[2], "wb");
|
||||||
|
if (!ofp)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "'%s' is not able to be opened for writing as a regular file\n", argv[2]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t decompSz = 0;
|
||||||
|
int numMips = 1;
|
||||||
|
|
||||||
|
z_stream z = {0};
|
||||||
|
size_t rowSz = 0;
|
||||||
|
uLong rowSzC = 0;
|
||||||
|
png_bytep row;
|
||||||
|
png_bytep rowC;
|
||||||
|
|
||||||
|
/* Get PNG data */
|
||||||
|
char header[8];
|
||||||
|
fread(header, 1, 8, fp);
|
||||||
|
if (png_sig_cmp((png_const_bytep)header, 0, 8))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "invalid PNG signature in '%s'\n", argv[1]);
|
||||||
|
fclose(fp);
|
||||||
|
fclose(ofp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
png_structp pngRead = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||||
|
if (!pngRead)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "unable to initialize libpng\n");
|
||||||
|
fclose(fp);
|
||||||
|
fclose(ofp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
png_infop info = png_create_info_struct(pngRead);
|
||||||
|
if (!info)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "unable to initialize libpng info\n");
|
||||||
|
fclose(fp);
|
||||||
|
fclose(ofp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setjmp(png_jmpbuf(pngRead)))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "unable to initialize libpng I/O for '%s'\n", argv[1]);
|
||||||
|
fclose(fp);
|
||||||
|
fclose(ofp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
png_init_io(pngRead, fp);
|
||||||
|
png_set_sig_bytes(pngRead, 8);
|
||||||
|
|
||||||
|
png_read_info(pngRead, info);
|
||||||
|
|
||||||
|
png_uint_32 width = png_get_image_width(pngRead, info);
|
||||||
|
png_uint_32 height = png_get_image_height(pngRead, info);
|
||||||
|
decompSz = width * height * 4;
|
||||||
|
png_byte colorType = png_get_color_type(pngRead, info);
|
||||||
|
png_byte bitDepth = png_get_bit_depth(pngRead, info);
|
||||||
|
|
||||||
|
if (colorType != PNG_COLOR_TYPE_RGB_ALPHA)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "'%s' is not in RGBA color mode\n", argv[1]);
|
||||||
|
fclose(fp);
|
||||||
|
fclose(ofp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bitDepth != 8)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "'%s' is not 8 bits-per-channel\n", argv[1]);
|
||||||
|
fclose(fp);
|
||||||
|
fclose(ofp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setjmp(png_jmpbuf(pngRead)))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "unable to read image in '%s'\n", argv[1]);
|
||||||
|
fclose(fp);
|
||||||
|
fclose(ofp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fmt = _bswap32(16);
|
||||||
|
uint16_t w = _bswap16(width);
|
||||||
|
uint16_t h = _bswap16(height);
|
||||||
|
uint32_t mips = _bswap32(numMips);
|
||||||
|
uint32_t dsz = _bswap32(decompSz);
|
||||||
|
fwrite(&fmt, 1, 4, ofp);
|
||||||
|
fwrite(&w, 1, 2, ofp);
|
||||||
|
fwrite(&h, 1, 2, ofp);
|
||||||
|
fwrite(&mips, 1, 4, ofp);
|
||||||
|
fwrite(&dsz, 1, 4, ofp);
|
||||||
|
|
||||||
|
rowSz = width*4;
|
||||||
|
rowSzC = compressBound(rowSz);
|
||||||
|
deflateInit(&z, Z_DEFAULT_COMPRESSION);
|
||||||
|
|
||||||
|
row = malloc(rowSz);
|
||||||
|
rowC = malloc(rowSzC);
|
||||||
|
|
||||||
|
for (png_uint_32 r=0 ; r<height ; ++r)
|
||||||
|
{
|
||||||
|
png_read_row(pngRead, row, NULL);
|
||||||
|
z.next_in = row;
|
||||||
|
z.avail_in = rowSz;
|
||||||
|
while (z.avail_in)
|
||||||
|
{
|
||||||
|
z.next_out = rowC;
|
||||||
|
z.avail_out = rowSzC;
|
||||||
|
z.total_out = 0;
|
||||||
|
deflate(&z, Z_NO_FLUSH);
|
||||||
|
fwrite(rowC, 1, z.total_out, ofp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
png_destroy_read_struct(&pngRead, &info, NULL);
|
||||||
|
|
||||||
|
int finishCycle = Z_OK;
|
||||||
|
while (finishCycle != Z_STREAM_END)
|
||||||
|
{
|
||||||
|
z.next_out = rowC;
|
||||||
|
z.avail_out = rowSzC;
|
||||||
|
z.total_out = 0;
|
||||||
|
finishCycle = deflate(&z, Z_FINISH);
|
||||||
|
fwrite(rowC, 1, z.total_out, ofp);
|
||||||
|
}
|
||||||
|
deflateEnd(&z);
|
||||||
|
free(row);
|
||||||
|
free(rowC);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue