#ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include "gd.h" /* A neat little utility which adds freetype text to * existing JPEG images. Type annotate -h for instructions. * Thanks to Joel Dubiner for supporting this work. -TBB */ enum { left, center, right }; int main(int argc, char *argv[]) { #ifndef HAVE_LIBFREETYPE (void)argc; (void)argv; /* 2.0.12 */ fprintf(stderr, "annotate is not useful without freetype.\n" "Install freetype, then './configure; make clean; make install'\n" "the gd library again.\n" ); return 1; #else gdImagePtr im; char *iin, *iout; FILE *in, *out; char s[1024]; int bounds[8]; int lines = 1; int color = gdTrueColor(0, 0, 0); char font[1024]; int size = 12; int align = left; int x = 0, y = 0; char *fontError; strcpy(font, "times"); if(argc != 3) { fprintf(stderr, "Usage: annotate imagein.jpg imageout.jpg\n\n"); fprintf(stderr, "Standard input should consist of\n"); fprintf(stderr, "lines in the following formats:\n"); fprintf(stderr, "color r g b (0-255 each) [a (0-127, 0 is opaque)]\n"); fprintf(stderr, "font fontname (max name length 1024)\n"); fprintf(stderr, "size pointsize\n"); fprintf(stderr, "align (left|right|center)\n"); fprintf(stderr, "move x y\n"); fprintf(stderr, "text actual-output-text\n\n"); fprintf(stderr, "If the file 'paris.ttf' exists in /usr/share/fonts/truetype or in a\n"); fprintf(stderr, "location specified in the GDFONTPATH environment variable, 'font paris' is\n"); fprintf(stderr, "sufficient. You may also specify the full, rooted path of a font file.\n"); exit(1); } iin = argv[1]; iout = argv[2]; in = fopen(iin, "rb"); if(!in) { fprintf(stderr, "Couldn't open %s\n", iin); exit(2); } #ifdef HAVE_LIBJPEG im = gdImageCreateFromJpeg(in); #else fprintf(stderr, "No JPEG library support available.\n"); exit(1); #endif fclose(in); if(!im) { fprintf(stderr, "%s did not load properly\n", iin); exit(3); } while(fgets(s, sizeof(s), stdin)) { char *st; char *text; st = strtok(s, " \t\r\n"); if(!st) { /* Be nice about blank lines */ continue; } if(!strcmp(st, "font")) { char *st = strtok(0, " \t\r\n"); if(!st) { goto badLine; } else { const unsigned int font_len = strlen(st); if (font_len >= 1024) { fprintf(stderr, "Font maximum length is 1024, %d given\n", font_len); goto badLine; } strncpy(font, st, font_len); } } else if(!strcmp(st, "align")) { char *st = strtok(0, " \t\r\n"); if(!st) { goto badLine; } if(!strcmp(st, "left")) { align = 0; } else if(!strcmp(st, "center")) { align = 1; } else if(!strcmp(st, "right")) { align = 2; } } else if(!strcmp(st, "size")) { char *st = strtok(0, " \t\r\n"); if(!st) { goto badLine; } size = atoi(st); } else if(!strcmp(st, "color")) { char *st = strtok(0, "\r\n"); int r, g, b, a = 0; if(!st) { goto badLine; } if(sscanf(st, "%d %d %d %d", &r, &g, &b, &a) < 3) { fprintf(stderr, "Bad color at line %d\n", lines); exit(2); } color = gdTrueColorAlpha(r, g, b, a); } else if(!strcmp(st, "move")) { char *st = strtok(0, "\r\n"); if(!st) { goto badLine; } if(sscanf(st, "%d %d", &x, &y) != 2) { fprintf(stderr, "Missing coordinates at line %d\n", lines); exit(3); } } else if(!strcmp(st, "text")) { int rx = x; text = strtok(0, "\r\n"); if(!text) { text = ""; } gdImageStringFT(0, bounds, color, font, size, 0, x, y, text); switch(align) { case left: break; case center: rx -= (bounds[2] - bounds[0]) / 2; break; case right: rx -= (bounds[2] - bounds[0]); break; } fontError = gdImageStringFT(im, 0, color, font, size, 0, rx, y, text); if(fontError) { fprintf(stderr, "font error at line %d: %s\n", lines, fontError); exit(7); } y -= (bounds[7] - bounds[1]); } else { goto badLine; } lines++; continue; badLine: fprintf(stderr, "Bad syntax, line %d\n", lines); exit(4); } out = fopen(iout, "wb"); if(!out) { fprintf(stderr, "Cannot create %s\n", iout); exit(5); } #ifdef HAVE_LIBJPEG gdImageJpeg(im, out, 95); #else fprintf(stderr, "No JPEG library support available.\n"); #endif gdImageDestroy(im); fclose(out); return 0; #endif /* HAVE_LIBFREETYPE */ }