resize-gd

annotate resize-gd.c @ 17:159402d54c29

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