packing and write implementation
parent
bd8194afc4
commit
02ddf8c5e1
|
@ -1,8 +1,8 @@
|
|||
cmake_minimum_required(VERSION 2.8.12)
|
||||
project(Cram C)
|
||||
|
||||
option(BUILD_CLI "Build command line executable" ON)
|
||||
option(BUILD_SHARED_LIBS "Build shared library" ON)
|
||||
option(USE_SDL2 "Use SDL2" ON)
|
||||
|
||||
SET(LIB_MAJOR_VERSION "0")
|
||||
SET(LIB_MINOR_VERSION "3")
|
||||
|
@ -38,11 +38,7 @@ if(UNIX)
|
|||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
|
||||
endif()
|
||||
|
||||
if(USE_SDL2)
|
||||
add_definitions(-DUSE_SDL2)
|
||||
endif()
|
||||
|
||||
add_library(Cram
|
||||
file(GLOB SOURCE_FILES
|
||||
#Public header
|
||||
include/cram.h
|
||||
#Source
|
||||
|
@ -51,6 +47,31 @@ add_library(Cram
|
|||
src/cram.c
|
||||
)
|
||||
|
||||
set(LINKSTYLE PRIVATE)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set(LINKSTYLE PUBLIC)
|
||||
endif()
|
||||
|
||||
if(BUILD_CLI)
|
||||
add_executable(cramcli
|
||||
tools/cli/dirent.h
|
||||
tools/cli/stb_image_write.h
|
||||
tools/cli/main.c
|
||||
)
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
target_link_libraries(cramcli PUBLIC Cram)
|
||||
else()
|
||||
target_link_libraries(cramcli PRIVATE Cram)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
add_library(Cram SHARED ${SOURCE_FILES})
|
||||
else()
|
||||
add_library(Cram STATIC ${SOURCE_FILES})
|
||||
endif()
|
||||
|
||||
# Build flags
|
||||
if(NOT MSVC)
|
||||
set_property(TARGET Cram PROPERTY COMPILE_FLAGS "-std=gnu99 -Wall -Wno-strict-aliasing -pedantic")
|
||||
|
@ -68,26 +89,3 @@ set_target_properties(Cram PROPERTIES OUTPUT_NAME "Cram"
|
|||
VERSION ${LIB_VERSION}
|
||||
SOVERSION ${LIB_MAJOR_VERSION}
|
||||
)
|
||||
|
||||
# SDL2 Dependency
|
||||
if(USE_SDL2)
|
||||
if (DEFINED SDL2_INCLUDE_DIRS AND DEFINED SDL2_LIBRARIES)
|
||||
message(STATUS "using pre-defined SDL2 variables SDL2_INCLUDE_DIRS and SDL2_LIBRARIES")
|
||||
target_include_directories(Cram PUBLIC "$<BUILD_INTERFACE:${SDL2_INCLUDE_DIRS}>")
|
||||
target_link_libraries(Cram PUBLIC ${SDL2_LIBRARIES})
|
||||
else()
|
||||
# Only try to autodetect if both SDL2 variables aren't explicitly set
|
||||
find_package(SDL2 CONFIG)
|
||||
if (TARGET SDL2::SDL2)
|
||||
message(STATUS "using TARGET SDL2::SDL2")
|
||||
target_link_libraries(Cram PUBLIC SDL2::SDL2)
|
||||
elseif (TARGET SDL2)
|
||||
message(STATUS "using TARGET SDL2")
|
||||
target_link_libraries(Cram PUBLIC SDL2)
|
||||
else()
|
||||
message(STATUS "no TARGET SDL2::SDL2, or SDL2, using variables")
|
||||
target_include_directories(Cram PUBLIC "$<BUILD_INTERFACE:${SDL2_INCLUDE_DIRS}>")
|
||||
target_link_libraries(Cram PUBLIC ${SDL2_LIBRARIES})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
@ -35,9 +35,7 @@
|
|||
#define CRAMCALL
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDL2
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
|
@ -97,9 +95,8 @@ typedef struct Cram_AtlasData
|
|||
CRAMAPI Cram_Context* Cram_Init(Cram_ContextCreateInfo *createInfo);
|
||||
|
||||
CRAMAPI void Cram_AddFile(Cram_Context *context, const char *path);
|
||||
CRAMAPI void Cram_AddFolder(Cram_Context *context, const char *path);
|
||||
|
||||
CRAMAPI void Cram_Pack(Cram_Context *context);
|
||||
CRAMAPI int8_t Cram_Pack(Cram_Context *context);
|
||||
|
||||
CRAMAPI void Cram_GetPixelData(Cram_Context *context, uint8_t **pPixelData, uint32_t *pWidth, uint32_t *pHeight);
|
||||
CRAMAPI void Cram_GetAtlasData(Cram_Context *context, Cram_AtlasData **pAtlasData);
|
||||
|
|
315
src/cram.c
315
src/cram.c
|
@ -26,18 +26,6 @@
|
|||
|
||||
#include "cram.h"
|
||||
|
||||
#ifdef USE_SDL2
|
||||
|
||||
#define Cram_assert SDL_assert
|
||||
#define Cram_qsort SDL_qsort
|
||||
#define Cram_malloc SDL_malloc
|
||||
#define Cram_realloc SDL_realloc
|
||||
#define Cram_free SDL_free
|
||||
#define Cram_memcpy SDL_memcpy
|
||||
#define Cram_strdup SDL_strdup
|
||||
|
||||
#else
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -47,18 +35,19 @@
|
|||
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
/* TODO: ifndefs here */
|
||||
#define Cram_assert assert
|
||||
#define Cram_qsort qsort
|
||||
#define Cram_malloc malloc
|
||||
#define Cram_realloc realloc
|
||||
#define Cram_free free
|
||||
#define Cram_memcpy memcpy
|
||||
#define Cram_memset memset
|
||||
#define Cram_strdup strdup
|
||||
|
||||
#endif /* USE_SDL2 */
|
||||
#define Cram_max max
|
||||
|
||||
#define STBRP_ASSERT Cram_assert
|
||||
#define STBRP_SORT Cram_sort
|
||||
#define STBRP_SORT Cram_qsort
|
||||
|
||||
#define STBRP_STATIC
|
||||
#define STB_RECT_PACK_IMPLEMENTATION
|
||||
|
@ -69,6 +58,7 @@
|
|||
#define STBI_REALLOC Cram_realloc
|
||||
#define STBI_FREE Cram_free
|
||||
|
||||
#define STBI_ONLY_PNG
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
|
||||
|
@ -76,15 +66,18 @@
|
|||
|
||||
/* Structures */
|
||||
|
||||
typedef struct Cram_ImageRect
|
||||
typedef struct Rect
|
||||
{
|
||||
int32_t x, y;
|
||||
int32_t w, h;
|
||||
} Rect;
|
||||
|
||||
typedef struct Cram_Image
|
||||
{
|
||||
const char *name;
|
||||
uint32_t offsetX;
|
||||
uint32_t offsetY;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
Rect rect;
|
||||
uint8_t *pixels;
|
||||
} Cram_ImageRect;
|
||||
} Cram_Image;
|
||||
|
||||
typedef struct Cram_Internal_Context
|
||||
{
|
||||
|
@ -97,9 +90,9 @@ typedef struct Cram_Internal_Context
|
|||
|
||||
uint8_t *pixels;
|
||||
|
||||
Cram_ImageRect *imageRects;
|
||||
uint32_t imageRectCount;
|
||||
uint32_t imageRectCapacity;
|
||||
Cram_Image *images;
|
||||
uint32_t imageCount;
|
||||
uint32_t imageCapacity;
|
||||
|
||||
Cram_AtlasData *atlasData;
|
||||
} Cram_Internal_Context;
|
||||
|
@ -123,9 +116,9 @@ Cram_Context* Cram_Init(Cram_ContextCreateInfo *createInfo)
|
|||
context->padding = createInfo->padding;
|
||||
context->trim = createInfo->trim;
|
||||
|
||||
context->imageRects = Cram_malloc(INITIAL_DATA_CAPACITY * sizeof(Cram_ImageRect));
|
||||
context->imageRectCapacity = INITIAL_DATA_CAPACITY;
|
||||
context->imageRectCount = 0;
|
||||
context->images = Cram_malloc(INITIAL_DATA_CAPACITY * sizeof(Cram_Image));
|
||||
context->imageCapacity = INITIAL_DATA_CAPACITY;
|
||||
context->imageCount = 0;
|
||||
|
||||
context->atlasData = Cram_malloc(sizeof(Cram_AtlasData));
|
||||
|
||||
|
@ -134,33 +127,91 @@ Cram_Context* Cram_Init(Cram_ContextCreateInfo *createInfo)
|
|||
return (Cram_Context*) context;
|
||||
}
|
||||
|
||||
static inline uint32_t GetPixelIndex(uint32_t i, uint32_t j, uint32_t width)
|
||||
static inline uint32_t Cram_Internal_GetPixelIndex(uint32_t x, uint32_t y, uint32_t width)
|
||||
{
|
||||
return (i + j * width) * 4;
|
||||
return x + y * width;
|
||||
}
|
||||
|
||||
/* width and height of source and destination rects must be the same! */
|
||||
static int8_t Cram_Internal_CopyPixels(
|
||||
uint32_t *dstPixels,
|
||||
uint32_t dstPixelWidth,
|
||||
uint32_t *srcPixels,
|
||||
uint32_t srcPixelWidth,
|
||||
Rect *dstRect,
|
||||
Rect *srcRect
|
||||
) {
|
||||
int32_t i, j;
|
||||
int32_t dstPixelIndex, srcPixelIndex;
|
||||
|
||||
if (dstRect->w != srcRect->w || dstRect->h != srcRect->h)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < dstRect->w; i += 1)
|
||||
{
|
||||
for (j = 0; j < dstRect->h; j += 1)
|
||||
{
|
||||
dstPixelIndex = Cram_Internal_GetPixelIndex(i + dstRect->x, j + dstRect->y, dstPixelWidth);
|
||||
srcPixelIndex = Cram_Internal_GetPixelIndex(i + srcRect->x, j + srcRect->y, srcPixelWidth);
|
||||
dstPixels[dstPixelIndex] = srcPixels[srcPixelIndex];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t Cram_Internal_IsRowClear(uint32_t* pixels, uint32_t rowIndex, uint32_t width)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
for (i = 0; i < width; i += 1)
|
||||
{
|
||||
if ((pixels[Cram_Internal_GetPixelIndex(i, rowIndex, width)] & 0xFF) > 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint8_t Cram_Internal_IsColumnClear(uint32_t* pixels, uint32_t columnIndex, uint32_t width, uint32_t height)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
for (i = 0; i < height; i += 1)
|
||||
{
|
||||
if ((pixels[Cram_Internal_GetPixelIndex(columnIndex, i, width)] & 0xFF) > 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Cram_AddFile(Cram_Context *context, const char *path)
|
||||
{
|
||||
Cram_Internal_Context *internalContext = (Cram_Internal_Context*) context;
|
||||
Cram_ImageRect *imageRect;
|
||||
Cram_Image *image;
|
||||
uint8_t *pixels;
|
||||
int32_t leftTrim, topTrim, rightTrim, bottomTrim;
|
||||
int32_t width, height, numChannels;
|
||||
uint32_t pixelIndex, pixelOffset;
|
||||
uint8_t allClear;
|
||||
int32_t i;
|
||||
|
||||
if (internalContext->imageRectCapacity == internalContext->imageRectCount)
|
||||
if (internalContext->imageCapacity == internalContext->imageCount)
|
||||
{
|
||||
internalContext->imageRectCapacity *= 2;
|
||||
internalContext->imageRects = Cram_realloc(internalContext->imageRects, internalContext->imageRectCapacity * sizeof(Cram_ImageRect));
|
||||
internalContext->imageCapacity *= 2;
|
||||
internalContext->images = Cram_realloc(internalContext->images, internalContext->imageCapacity * sizeof(Cram_Image));
|
||||
}
|
||||
|
||||
imageRect = &internalContext->imageRects[internalContext->imageRectCount];
|
||||
image = &internalContext->images[internalContext->imageCount];
|
||||
|
||||
imageRect->name = Cram_Internal_GetTrimmedPath();
|
||||
/* image->name = Cram_Internal_GetTrimmedPath(); */
|
||||
|
||||
pixels = stbi_load_from_file(
|
||||
pixels = stbi_load(
|
||||
path,
|
||||
&width,
|
||||
&height,
|
||||
|
@ -168,124 +219,152 @@ void Cram_AddFile(Cram_Context *context, const char *path)
|
|||
STBI_rgb_alpha
|
||||
);
|
||||
|
||||
/* Check for trim */
|
||||
if (internalContext->trim)
|
||||
{
|
||||
/* Check for trim */
|
||||
allClear = 1;
|
||||
topTrim = -1;
|
||||
|
||||
while (allClear)
|
||||
topTrim = 0;
|
||||
for (i = 0; i < height; i += 1)
|
||||
{
|
||||
topTrim += 1;
|
||||
|
||||
for (i = 0; i < width; i += 1)
|
||||
if (!Cram_Internal_IsRowClear(pixels, i, width))
|
||||
{
|
||||
pixelIndex = GetPixelIndex(i, topTrim, width);
|
||||
|
||||
/* alpha check */
|
||||
if (pixels[pixelIndex + 3] > 0)
|
||||
{
|
||||
allClear = 0;
|
||||
break;
|
||||
}
|
||||
topTrim = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
allClear = 1;
|
||||
leftTrim = -1;
|
||||
|
||||
while (allClear)
|
||||
leftTrim = 0;
|
||||
for (i = 0; i < width; i += 1)
|
||||
{
|
||||
leftTrim += 1;
|
||||
|
||||
for (i = topTrim; i < height; i += 1)
|
||||
if (!Cram_Internal_IsColumnClear(pixels, i, width, height))
|
||||
{
|
||||
pixelIndex = GetPixelIndex(leftTrim, i, width);
|
||||
|
||||
if (pixels[pixelIndex + 3] > 0)
|
||||
{
|
||||
allClear = 0;
|
||||
break;
|
||||
}
|
||||
leftTrim = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
allClear = 1;
|
||||
bottomTrim = -1;
|
||||
|
||||
while (allClear)
|
||||
bottomTrim = height;
|
||||
for (i = height - 1; i >= topTrim; i -= 1)
|
||||
{
|
||||
bottomTrim += 1;
|
||||
|
||||
for (i = width - 1; i >= leftTrim; i -= 1)
|
||||
if (!Cram_Internal_IsRowClear(pixels, i, width))
|
||||
{
|
||||
pixelIndex = GetPixelIndex(i, bottomTrim, width);
|
||||
|
||||
if (pixels[pixelIndex + 3] > 0)
|
||||
{
|
||||
allClear = 0;
|
||||
break;
|
||||
}
|
||||
bottomTrim = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
allClear = 1;
|
||||
rightTrim = -1;
|
||||
|
||||
while (allClear)
|
||||
rightTrim = width;
|
||||
for (i = width - 1; i >= leftTrim; i -= 1)
|
||||
{
|
||||
rightTrim += 1;
|
||||
|
||||
for (i = height - 1; i >= topTrim; i -= 1)
|
||||
if (!Cram_Internal_IsColumnClear(pixels, i, width, height))
|
||||
{
|
||||
pixelIndex = GetPixelIndex(rightTrim, i, width);
|
||||
|
||||
if (pixels[pixelIndex + 3] > 0)
|
||||
{
|
||||
allClear = 0;
|
||||
break;
|
||||
}
|
||||
rightTrim = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
imageRect->offsetX = leftTrim;
|
||||
imageRect->offsetY = topTrim;
|
||||
imageRect->width = width - rightTrim;
|
||||
imageRect->height = height - bottomTrim;
|
||||
image->rect.x = leftTrim;
|
||||
image->rect.y = topTrim;
|
||||
image->rect.w = rightTrim - leftTrim;
|
||||
image->rect.h = bottomTrim - topTrim;
|
||||
}
|
||||
else
|
||||
{
|
||||
imageRect->offsetX = 0;
|
||||
imageRect->offsetY = 0;
|
||||
imageRect->width = width;
|
||||
imageRect->height = height;
|
||||
image->rect.x = 0;
|
||||
image->rect.y = 0;
|
||||
image->rect.w = width;
|
||||
image->rect.h = height;
|
||||
}
|
||||
/* copy */
|
||||
imageRect->pixels = Cram_malloc(imageRect->width * imageRect->height * 4);
|
||||
|
||||
pixelOffset = GetPixelIndex(imageRect->offsetX, imageRect->offsetY, width);
|
||||
Cram_memcpy(imageRect->pixels, pixels + pixelOffset, (width * height * 4) - pixelOffset);
|
||||
/* copy */
|
||||
image->pixels = Cram_malloc(image->rect.w * image->rect.h * 4);
|
||||
|
||||
Rect dstRect;
|
||||
dstRect.x = 0;
|
||||
dstRect.y = 0;
|
||||
dstRect.w = image->rect.w;
|
||||
dstRect.h = image->rect.h;
|
||||
Cram_Internal_CopyPixels((uint32_t*) image->pixels, image->rect.w, (uint32_t*) pixels, width, &dstRect, &image->rect);
|
||||
|
||||
stbi_image_free(pixels);
|
||||
|
||||
internalContext->imageRectCount += 1;
|
||||
internalContext->imageCount += 1;
|
||||
}
|
||||
|
||||
void Cram_AddFolder(Cram_Context *context, const char *path)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Cram_Pack(Cram_Context *context)
|
||||
int8_t Cram_Pack(Cram_Context *context)
|
||||
{
|
||||
stbrp_context rectPackContext;
|
||||
Cram_Internal_Context *internalContext = (Cram_Internal_Context*) context;
|
||||
uint32_t numNodes = internalContext->width;
|
||||
stbrp_node *nodes = Cram_malloc(sizeof(stbrp_node*) * numNodes);
|
||||
stbrp_node *nodes = Cram_malloc(sizeof(stbrp_node) * numNodes);
|
||||
stbrp_rect *rects = Cram_malloc(sizeof(stbrp_rect) * internalContext->imageCount);
|
||||
stbrp_rect *rect;
|
||||
Rect dstRect, srcRect;
|
||||
int32_t i;
|
||||
uint32_t maxWidth = 0;
|
||||
uint32_t maxHeight = 0;
|
||||
|
||||
stbrp_init_target(&rectPackContext, internalContext->width, internalContext->height, nodes, numNodes);
|
||||
|
||||
/* TODO: pack rects */
|
||||
for (i = 0; i < internalContext->imageCount; i += 1)
|
||||
{
|
||||
rect = &rects[i];
|
||||
|
||||
rect->w = internalContext->images[i].rect.w + internalContext->padding;
|
||||
rect->h = internalContext->images[i].rect.h + internalContext->padding;
|
||||
}
|
||||
|
||||
stbrp_pack_rects(&rectPackContext, rects, internalContext->imageCount);
|
||||
|
||||
for (i = 0; i < internalContext->imageCount; i += 1)
|
||||
{
|
||||
rect = &rects[i];
|
||||
|
||||
if (rect->was_packed)
|
||||
{
|
||||
internalContext->images[i].rect.x = rect->x;
|
||||
internalContext->images[i].rect.y = rect->y;
|
||||
|
||||
maxWidth = Cram_max(maxWidth, rect->x + rect->w);
|
||||
maxHeight = Cram_max(maxHeight, rect->y + rect->h);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
internalContext->width = maxWidth;
|
||||
internalContext->height = maxHeight;
|
||||
|
||||
internalContext->pixels = Cram_realloc(internalContext->pixels, internalContext->width * internalContext->height * 4);
|
||||
Cram_memset(internalContext->pixels, 0, internalContext->width * internalContext->height * 4);
|
||||
|
||||
for (i = 0; i < internalContext->imageCount; i += 1)
|
||||
{
|
||||
dstRect.x = internalContext->images[i].rect.x;
|
||||
dstRect.y = internalContext->images[i].rect.y;
|
||||
dstRect.w = internalContext->images[i].rect.w;
|
||||
dstRect.h = internalContext->images[i].rect.h;
|
||||
|
||||
srcRect.x = 0;
|
||||
srcRect.y = 0;
|
||||
srcRect.w = internalContext->images[i].rect.w;
|
||||
srcRect.h = internalContext->images[i].rect.h;
|
||||
|
||||
Cram_Internal_CopyPixels(
|
||||
(uint32_t*) internalContext->pixels,
|
||||
internalContext->width,
|
||||
(uint32_t*) internalContext->images[i].pixels,
|
||||
internalContext->images[i].rect.w,
|
||||
&dstRect,
|
||||
&srcRect
|
||||
);
|
||||
}
|
||||
|
||||
Cram_free(nodes);
|
||||
Cram_free(rects);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Cram_GetPixelData(Cram_Context *context, uint8_t **pPixels, uint32_t *pWidth, uint32_t *pHeight)
|
||||
|
@ -310,7 +389,7 @@ void Cram_Destroy(Cram_Context *context)
|
|||
Cram_free(internalContext);
|
||||
}
|
||||
|
||||
Cram_free(internalContext->imageRects);
|
||||
Cram_free(internalContext->images);
|
||||
Cram_free(internalContext->atlasData);
|
||||
Cram_free(internalContext);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,115 @@
|
|||
#include "cram.h"
|
||||
#include "dirent.h"
|
||||
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include "stb_image_write.h"
|
||||
|
||||
#define MAX_DIR_LENGTH 2048
|
||||
|
||||
static Cram_Context *context;
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define SEPARATOR "\\"
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __unix__
|
||||
|
||||
#define SEPARATOR "/"
|
||||
|
||||
#endif
|
||||
|
||||
static const char* GetFilenameExtension(const char *filename)
|
||||
{
|
||||
const char *dot = strrchr(filename, '.');
|
||||
if (!dot || dot == filename)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return dot + 1;
|
||||
}
|
||||
|
||||
/* Mostly taken from K&R C 2nd edition page 182 */
|
||||
static void dirwalk(char *dir)
|
||||
{
|
||||
dirent *dp;
|
||||
DIR *dfd;
|
||||
char subname[2048];
|
||||
|
||||
if ((dfd = opendir(dir)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "Can't open %s\n", dir);
|
||||
return;
|
||||
}
|
||||
|
||||
while ((dp = readdir(dfd)) != NULL)
|
||||
{
|
||||
if ( strcmp(dp->d_name, ".") == 0 ||
|
||||
strcmp(dp->d_name, "..") == 0
|
||||
)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
sprintf(subname, "%s%s%s", dir, SEPARATOR, dp->d_name);
|
||||
|
||||
if (dp->d_type == DT_DIR)
|
||||
{
|
||||
dirwalk(subname);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strcmp(GetFilenameExtension(subname), "png") == 0)
|
||||
{
|
||||
Cram_AddFile(context, subname);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stdout, "skipping %s\n", subname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dfd);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Cram_ContextCreateInfo createInfo;
|
||||
uint8_t *pixelData;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
fprintf(stderr, "Must provide directory!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
createInfo.padding = 0;
|
||||
createInfo.trim = 1;
|
||||
createInfo.maxDimension = 8192;
|
||||
createInfo.name = "test";
|
||||
|
||||
context = Cram_Init(&createInfo);
|
||||
|
||||
dirwalk(argv[1]);
|
||||
|
||||
Cram_Pack(context);
|
||||
|
||||
Cram_GetPixelData(context, &pixelData, &width, &height);
|
||||
|
||||
stbi_write_png(
|
||||
"output.png",
|
||||
width,
|
||||
height,
|
||||
4,
|
||||
pixelData,
|
||||
width * 4
|
||||
);
|
||||
|
||||
Cram_Destroy(context);
|
||||
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue