Skip to content

Image Converter — C source

Convert images between PNG, JPEG and WebP entirely in your browser. Batch-friendly with quality control and a before/after size delta — nothing is uploaded.

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

/* Image converter — C port of the image-converter tool. */

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Convert an image file to PNG or JPEG. JPEG has no alpha channel:
 * flatten onto white first, or transparent pixels render black. */
static int convert_image(const char *src, const char *dst, int to_jpeg,
                         int quality) {
    int w, h, n;
    unsigned char *rgba = stbi_load(src, &w, &h, &n, 4);
    if (!rgba) {
        fprintf(stderr, "decode failed: %s\n", stbi_failure_reason());
        return 1;
    }

    if (to_jpeg) {
        for (int i = 0; i < w * h; i++) {
            unsigned char *px = rgba + i * 4;
            unsigned char a = px[3];
            for (int c = 0; c < 3; c++) /* source-over white, rounded */
                px[c] = (unsigned char)((px[c] * a + 255 * (255 - a) + 127) / 255);
            px[3] = 255;
        }
    }

    /* stb writes JPEG (RGB, alpha ignored) and PNG (RGBA). Quality is
     * 1..100; the web tool's 0..1 slider multiplies by 100. */
    int ok = to_jpeg ? stbi_write_jpg(dst, w, h, 4, rgba, quality)
                     : stbi_write_png(dst, w, h, 4, rgba, w * 4);
    if (!ok)
        fprintf(stderr, "encode failed\n");
    stbi_image_free(rgba);
    return ok ? 0 : 1;
}

int main(int argc, char **argv) {
    if (argc != 4) {
        fprintf(stderr, "usage: %s input.png output.jpg|png 85\n", argv[0]);
        return 1;
    }
    const char *ext = strrchr(argv[2], '.');
    int to_jpeg = ext && (strcmp(ext, ".jpg") == 0 || strcmp(ext, ".jpeg") == 0);
    return convert_image(argv[1], argv[2], to_jpeg, atoi(argv[3]));
}

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 →