resize-gd

view resize-gd.c @ 10:6b8e8fcd6d4d

added error handling
author meillo@marmaro.de
date Sat, 14 Jun 2008 18:08:03 +0200
parents c0045d8d3ce2
children 6f5c3a02e4d5
line source
1 /*
2 * resize-gd - resizes images using the gd-library
3 *
4 * Copyright 2008 by markus schnalke <meillo@marmaro.de>
5 *
6 * build-depends: libgd2-noxpm-dev | libgd2-dev
7 * depends: libgd2-noxpm | libgd2-xpm
8 */
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <ctype.h>
14 #include "gd.h"
16 #define PROGRAM "resize-gd"
17 #define VERSION "0.2"
19 enum {
20 Png,
21 Jpg
22 };
24 struct size {
25 int w;
26 int h;
27 };
30 void
31 version() {
32 printf("%s version: %s\n", PROGRAM, VERSION);
33 }
36 void
37 usage() {
38 printf("\
39 usage: %s <size> <imagefiles> [...]\n\
40 (keeps aspect ratio, does not enlarge images)\n\
41 %s <width>x<height> <imagefiles> [...]\n\
42 (resizes to that size, enlarges if needed)\n\
43 ", PROGRAM, PROGRAM);
44 }
47 struct size
48 calcsize(struct size opt, struct size img, int enlarge) {
49 struct size result;
51 if (opt.h <= 0) {
52 /* keep aspect ratio */
53 if (!enlarge && opt.w > img.w && opt.w > img.h) {
54 opt.w = (img.w > img.h) ? img.w : img.h;
55 }
56 if (img.w > img.h) {
57 result.w = opt.w;
58 result.h = opt.w * (1.0 * img.h / img.w);
59 } else {
60 result.h = opt.w;
61 result.w = opt.w * (1.0 * img.w / img.h);
62 }
63 } else {
64 result = opt;
65 }
66 return result;
67 }
70 int
71 validsize(char* sp) {
72 while (isdigit(*sp)) {
73 sp++;
74 }
75 if (*sp == 'x' && isdigit(*(sp+1))) {
76 sp++;
77 while (isdigit(*sp)) {
78 sp++;
79 }
80 }
81 if (*sp != '\0') {
82 return 0;
83 }
84 return 1;
85 }
88 int
89 main(int argc, char* argv[]) {
90 int i;
91 int type;
92 gdImagePtr im_in;
93 gdImagePtr im_out;
94 FILE* in;
95 FILE* out;
96 char* c;
97 struct size sizeopt, sizeimg, sizedest;
99 if (argc == 2 && strcmp(argv[1], "--version") == 0) {
100 version();
101 exit(0);
102 }
103 if (argc == 2 && strcmp(argv[1], "--help") == 0) {
104 version();
105 usage();
106 exit(0);
107 }
108 if (argc < 3) {
109 usage();
110 exit(1);
111 }
113 if (!validsize(argv[1])) {
114 fprintf(stderr, "Invalid form of size. Has to be <size> or <width>x<height>.\n");
115 usage();
116 exit(2);
117 }
119 /* parse width and height */
120 sizeopt.w = atoi(argv[1]);
121 c = strstr(argv[1], "x");
122 if (c && c[1] != '\0') {
123 sizeopt.h = atoi(c + 1);
124 } else {
125 sizeopt.h = -1; /* keep aspect ratio */
126 }
129 /* process images */
130 for (i = 2; i < argc; i++) {
131 /* printf("processing file '%s'\n", argv[i]); */
133 if (strcmp(argv[i]+strlen(argv[i])-4, ".png") == 0) {
134 type = Png;
135 } else if (strcmp(argv[i]+strlen(argv[i])-4, ".jpg") == 0) {
136 type = Jpg;
137 } else {
138 fprintf(stderr, "'%s' has unknown filetype. Filename must end with (lowercase) '.png' or '.jpg'.\n", argv[i]);
139 continue;
140 }
142 /* load image */
143 in = fopen(argv[i], "rb");
144 if (in == NULL) {
145 fprintf(stderr, "unable to open '%s' for reading\n", argv[i]);
146 continue;
147 }
148 if (type == Png) {
149 im_in = gdImageCreateFromPng(in);
150 } else if (type == Jpg) {
151 im_in = gdImageCreateFromJpeg(in);
152 }
153 if (im_in == NULL) {
154 fprintf(stderr, "unable to load image '%s'\n", argv[i]);
155 continue;
156 }
157 fclose(in);
159 /* calculate target size */
160 sizeimg.w = im_in->sx;
161 sizeimg.h = im_in->sy;
162 sizedest = calcsize(sizeopt, sizeimg, 0);
164 /* skip images that dont need to be resized */
165 if (sizedest.w == sizeimg.w && sizedest.h == sizeimg.h) {
166 gdImageDestroy(im_in);
167 continue;
168 }
170 /* copy-resize the image */
171 im_out = gdImageCreateTrueColor(sizedest.w, sizedest.h);
172 if (im_out == NULL) {
173 fprintf(stderr, "unable to allocate memory for resized image\n");
174 exit(3);
175 }
176 gdImageCopyResampled(im_out, im_in, 0, 0, 0, 0, im_out->sx, im_out->sy, im_in->sx, im_in->sy);
178 /* write image */
179 out = fopen(argv[i], "wb");
180 if (out == NULL) {
181 fprintf(stderr, "unable to open '%s' for writing\n", argv[i]);
182 continue;
183 }
184 if (type == Png) {
185 gdImagePng(im_out, out);
186 } else if (type == Jpg) {
187 gdImageJpeg(im_out, out, -1);
188 }
189 fclose(out);
191 gdImageDestroy(im_in);
192 gdImageDestroy(im_out);
193 }
195 return 0;
196 }