Skip to content

App Icon Generator — C source

Turn one image into the full web app icon set — favicon, apple-touch-icon and manifest sizes as crisp PNGs. Letterboxed contain-fit, optional white background — runs entirely in your browser.

This is the C implementation — the same logic the interactive tool runs, in a shareable, citable form.

/* App Icon Generator — contain-fit, centered export geometry for the
 * 16/32/180/192/512 icon set (C11, stdlib only). Port of
 * src/tool-sources/app-icon-generator/typescript.ts (the authored canvas snippet). */
#include <stddef.h>

static const int ICON_SIZES[] = {16, 32, 180, 192, 512};
enum { ICON_SIZES_COUNT = sizeof ICON_SIZES / sizeof ICON_SIZES[0] };

typedef struct {
    int size; /* canvas edge (px x px) this rect was fitted into */
    int x, y; /* top-left offset: centers the fitted image */
    int w, h; /* fitted image size, at least 1x1 */
} icon_rect;

/* The deterministic half of the tool: for every export size, compute the
 * contain-fit rect (scale = min(px/w, px/h), never upscale-biased, clamped to
 * >= 1) and the centered draw offset — exactly the geometry the TS pipeline
 * feeds to ctx.drawImage before canvas.toBlob PNG-encodes each square.
 * Rounding mirrors JS Math.round (half away from zero); all inputs are
 * positive, so floor(v + 0.5) is exact and needs no libm. Returns the number
 * of rects written; `out` must hold at least `n` entries. */
size_t icon_set_plan(int src_w, int src_h, const int *sizes, size_t n, icon_rect *out)
{
    for (size_t i = 0; i < n; i++) {
        int px = sizes[i];
        double scale = px / (double) src_w < px / (double) src_h
                           ? px / (double) src_w
                           : px / (double) src_h;
        int w = (int) (src_w * scale + 0.5);
        int h = (int) (src_h * scale + 0.5);
        if (w < 1) w = 1; /* max(1, ...) — a 1px source still yields a 1px icon */
        if (h < 1) h = 1;
        out[i].size = px;
        out[i].w = w;
        out[i].h = h;
        out[i].x = (int) ((px - w) / 2.0 + 0.5); /* letterbox on transparency */
        out[i].y = (int) ((px - h) / 2.0 + 0.5);
    }
    return n;
}

/* Convenience wrapper over the default export set. */
size_t icon_set_plan_default(int src_w, int src_h, icon_rect *out)
{
    return icon_set_plan(src_w, src_h, ICON_SIZES, ICON_SIZES_COUNT, out);
}

Also available in 8 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →