view resize-gd.c @ 9:a3547175f466

added license file
author meillo@marmaro.de
date Sat, 14 Jun 2008 18:07:51 +0200
parents c0045d8d3ce2
children 6b8e8fcd6d4d
line wrap: on
line source

/*
 * resize-gd - resizes images using the gd-library
 *
 * Copyright 2008 by markus schnalke <meillo@marmaro.de>
 *
 * build-depends: libgd2-noxpm-dev | libgd2-dev
 * depends: libgd2-noxpm | libgd2-xpm
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "gd.h"

#define PROGRAM "resize-gd"
#define VERSION "0.1"

enum {
	Png,
	Jpg
};

struct size {
	int w;
	int h;
};


void
version() {
	printf("%s version: %s\n", PROGRAM, VERSION);
}


void
usage() {
	printf("\
usage: %s <size> <imagefiles> [...]\n\
         (keeps aspect ratio, does not enlarge images)\n\
       %s <width>x<height> <imagefiles> [...]\n\
         (resizes to that size, enlarges if needed)\n\
", PROGRAM, PROGRAM);
}


struct size
calcsize(struct size opt, struct size img, int enlarge) {
	struct size result;

	if (opt.h <= 0) {
		/* keep aspect ratio */
		if (!enlarge && opt.w > img.w && opt.w > img.h) {
			opt.w = (img.w > img.h) ? img.w : img.h;
		}
		if (img.w > img.h) {
			result.w = opt.w;
			result.h = opt.w * (1.0 * img.h / img.w);
		} else {
			result.h = opt.w;
			result.w = opt.w * (1.0 * img.w / img.h);
		}
	} else {
		result = opt;
	}
	return result;
}


int
validsize(char* sp) {
	while (isdigit(*sp)) {
		sp++;
	}
	if (*sp == 'x' && isdigit(*(sp+1))) {
		sp++;
		while (isdigit(*sp)) {
			sp++;
		}
	}
	if (*sp != '\0') {
		return 0;
	}
	return 1;
}


int
main(int argc, char* argv[]) {
	int i;
	int type;
	gdImagePtr im_in;
	gdImagePtr im_out;
	FILE* in;
	FILE* out;
	char* c;
	struct size sizeopt, sizeimg, sizedest;

	if (argc == 2 && strcmp(argv[1], "--version") == 0) {
		version();
		exit(0);
	}
	if (argc == 2 && strcmp(argv[1], "--help") == 0) {
		version();
		usage();
		exit(0);
	}
	if (argc < 3) {
		usage();
		exit(1);
	}

	if (!validsize(argv[1])) {
		fprintf(stderr, "Invalid form of size. Has to be <size> or <width>x<height>.\n");
		usage();
		exit(2);
	}

	/* parse width and height */
	sizeopt.w = atoi(argv[1]);
	c = strstr(argv[1], "x");
	if (c && c[1] != '\0') {
		sizeopt.h = atoi(c + 1);
	} else {
		sizeopt.h = -1;  /* keep aspect ratio */
	}


	/* process images */
	for (i = 2; i < argc; i++) {
		printf("processing file '%s'\n", argv[i]);

		if (strcmp(argv[i]+strlen(argv[i])-4, ".png") == 0) {
			type = Png;
		} else if (strcmp(argv[i]+strlen(argv[i])-4, ".jpg") == 0) {
			type = Jpg;
		} else {
			fprintf(stderr, "'%s' has unknown filetype. Filename must end with (lowercase) '.png' or '.jpg'.\n", argv[i]);
			continue;
		}

		/* load image */
		in = fopen(argv[i], "rb");
		if (type == Png) {
			im_in = gdImageCreateFromPng(in);
		} else if (type == Jpg) {
			im_in = gdImageCreateFromJpeg(in);
		}
		fclose(in);

		/* calculate target size */
		sizeimg.w = im_in->sx;
		sizeimg.h = im_in->sy;
		sizedest = calcsize(sizeopt, sizeimg, 0);

		/* skip images that dont need to be resized */
		if (sizedest.w == sizeimg.w && sizedest.h == sizeimg.h) {
			gdImageDestroy(im_in);
			continue;
		}

		/* copy-resize the image */
		im_out = gdImageCreateTrueColor(sizedest.w, sizedest.h);
		gdImageCopyResampled(im_out, im_in, 0, 0, 0, 0, im_out->sx, im_out->sy, im_in->sx, im_in->sy);

		/* write image */
		out = fopen(argv[i], "wb");
		if (type == Png) {
			gdImagePng(im_out, out);
		} else if (type == Jpg) {
			gdImageJpeg(im_out, out, -1);
		}
		fclose(out);

		gdImageDestroy(im_in);
		gdImageDestroy(im_out);
	}

	return 0;
}