Skip to content

Commit

Permalink
misc: quantize png images to reduce filesize
Browse files Browse the repository at this point in the history
  • Loading branch information
jsm174 committed Nov 21, 2023
1 parent 526fe9b commit 40dd4ef
Show file tree
Hide file tree
Showing 6 changed files with 9,170 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
steps:
- run: |
sudo apt-get update
sudo apt-get install libsdl2-dev libsdl2-image-dev
sudo apt-get install libsdl2-dev libsdl2-image-dev libimagequant-dev
- uses: actions/checkout@v3
- name: Build
run: |
Expand Down
31 changes: 25 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,44 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")

find_package(PkgConfig REQUIRED)
find_package(X11 REQUIRED)
find_package(OpenMP REQUIRED)

pkg_check_modules(SDL2 REQUIRED sdl2)
pkg_check_modules(SDL2_IMAGE REQUIRED SDL2_image)
pkg_check_modules(IMAGEQUANT REQUIRED imagequant)

include_directories(
${CMAKE_SOURCE_DIR}
${X11_INCLUDE_DIR}
${SDL2_INCLUDE_DIRS}
${SDL2_IMAGE_INCLUDE_DIRS}
${IMAGEQUANT_INCLUDE_DIRS}
)

include_directories(${CMAKE_SOURCE_DIR} ${X11_INCLUDE_DIR} ${SDL2_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIRS})

link_directories(${SDL2_LIBRARY_DIRS} ${SDL2_IMAGE_LIBRARY_DIRS})
link_directories(
${SDL2_LIBRARY_DIRS}
${SDL2_IMAGE_LIBRARY_DIRS}
${IMAGEQUANT_LIBRARY_DIRS}
)

add_executable(vpxds
main.cpp
VPXDisplayServer.h
VPXDisplayServer.cpp
inc/mongoose/mongoose.c
inc/mongoose/mongoose.h
inc/lodepng/lodepng.cpp
inc/lodepng/lodepng.h
)

target_link_libraries(vpxds ${SDL2_LIBRARIES} ${SDL2_IMAGE_LIBRARIES} ${X11_LIBRARIES})

target_link_libraries(vpxds
${SDL2_LIBRARIES}
${SDL2_IMAGE_LIBRARIES}
${X11_LIBRARIES}
libimagequant.a
OpenMP::OpenMP_CXX
)

add_custom_command(TARGET vpxds POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_SOURCE_DIR}/assets" "$<TARGET_FILE_DIR:vpxds>/assets"
)
)
66 changes: 63 additions & 3 deletions VPXDisplayServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
#include "inc/mongoose/mongoose.h"
#include "inc/mINI/ini.h"
#include "inc/subprocess/subprocess.h"
#include "inc/lodepng/lodepng.h"

#include <iostream>
#include <filesystem>
#include <algorithm>
#include <X11/Xlib.h>

#include <libimagequant.h>

static VPXDisplayServer* g_pServer = NULL;

void VPXDisplayServer::Forward(struct mg_http_message *hm, struct mg_connection *c)
Expand Down Expand Up @@ -234,7 +237,7 @@ void VPXDisplayServer::Capture(struct mg_connection *c, void *ev_data)
int process_return;
if (!subprocess_join(&subprocess, &process_return)) {
PLOGI.printf("process return: %d", process_return);
if (!process_return) {
if (!process_return && ProcessPNG(szCapture)) {
mg_http_reply(c, 200, "", "");
return;
}
Expand Down Expand Up @@ -281,9 +284,9 @@ void VPXDisplayServer::CaptureES(struct mg_connection *c, void *ev_data)
int process_return;
if (!subprocess_join(&subprocess, &process_return)) {
PLOGI.printf("process returned: %d", process_return);
if (!process_return) {
if (!process_return && ProcessPNG(szPath)) {
struct mg_http_serve_opts opts = {};
mg_http_serve_file(c, hm, szPath.c_str(), &opts);
mg_http_serve_file(c, hm, szPath.c_str(), &opts);
return;
}
}
Expand Down Expand Up @@ -454,6 +457,63 @@ void VPXDisplayServer::LoadINI()
}
}

bool VPXDisplayServer::ProcessPNG(const std::string& filename)
{
unsigned int width;
unsigned int height;
unsigned char* pPixels;

if (lodepng_decode32_file(&pPixels, &width, &height, filename.c_str()))
return false;

liq_attr* pHandle = liq_attr_create();
liq_image* pImage = liq_image_create_rgba(pHandle, pPixels, width, height, 0);

liq_result* pQuantizationResult;
if (liq_image_quantize(pImage, pHandle, &pQuantizationResult) != LIQ_OK)
return false;

size_t pixelsSize = width * height;
unsigned char* pPixels8 = (unsigned char *)malloc(pixelsSize);
liq_set_dithering_level(pQuantizationResult, 1.0);

liq_write_remapped_image(pQuantizationResult, pImage, pPixels8, pixelsSize);
const liq_palette* pPalette = liq_get_palette(pQuantizationResult);

LodePNGState state;
lodepng_state_init(&state);
state.info_raw.colortype = LCT_PALETTE;
state.info_raw.bitdepth = 8;
state.info_png.color.colortype = LCT_PALETTE;
state.info_png.color.bitdepth = 8;

for (int i = 0; i < pPalette->count; i++) {
lodepng_palette_add(&state.info_png.color, pPalette->entries[i].r, pPalette->entries[i].g, pPalette->entries[i].b, pPalette->entries[i].a);
lodepng_palette_add(&state.info_raw, pPalette->entries[i].r, pPalette->entries[i].g, pPalette->entries[i].b, pPalette->entries[i].a);
}

unsigned char* pOutput;
size_t outputSize;
if (lodepng_encode(&pOutput, &outputSize, pPixels8, width, height, &state))
return false;

FILE *fp = fopen(filename.c_str(), "wb");
if (!fp)
return false;

fwrite(pOutput, 1, outputSize, fp);
fclose(fp);

liq_result_destroy(pQuantizationResult);
liq_image_destroy(pImage);
liq_attr_destroy(pHandle);

free(pPixels8);
lodepng_state_cleanup(&state);

return true;
}

int VPXDisplayServer::Start()
{
PLOGI << "Starting VPXDS...";
Expand Down
1 change: 1 addition & 0 deletions VPXDisplayServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class VPXDisplayServer
void Reset(struct mg_connection *c, void *ev_data);
void Capture(struct mg_connection *c, void *ev_data);
void CaptureES(struct mg_connection *c, void *ev_data);
bool ProcessPNG(const std::string& filename);

VPXDisplay* m_pBackglassDisplay;
VPXDisplay* m_pDMDDisplay;
Expand Down
Loading

0 comments on commit 40dd4ef

Please sign in to comment.