diff options
Diffstat (limited to 'debian/transcode/transcode-1.1.7/import/tcxpm2rgb.c')
| -rw-r--r-- | debian/transcode/transcode-1.1.7/import/tcxpm2rgb.c | 430 |
1 files changed, 430 insertions, 0 deletions
diff --git a/debian/transcode/transcode-1.1.7/import/tcxpm2rgb.c b/debian/transcode/transcode-1.1.7/import/tcxpm2rgb.c new file mode 100644 index 00000000..4e7c2df8 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/import/tcxpm2rgb.c @@ -0,0 +1,430 @@ +/* + * tcxpm2rgb.c + * + * Copyright (C) Tilmann Bitterberg - September 2003 + * + * This file is part of transcode, a video stream processing tool + * + * transcode is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include "transcode.h" +#include "ioaux.h" + +#include <ctype.h> + + +/* ParseColor and QueryColorDatabase are from ImageMagick */ + +static char *ParseColor(char *data) +{ +#define NumberTargets 6 + + static const char + *targets[NumberTargets] = { "c ", "g ", "g4 ", "m ", "b ", "s " }; + + register char + *p, + *r; + + register const char + *q; + + register int + i; + + for (i=0; i < NumberTargets; i++) + { + r=data; + for (q=targets[i]; *r != '\0'; r++) + { + if (*r != *q) + continue; + if (!isspace((int) (*(r-1)))) + continue; + p=r; + for ( ; ; ) + { + if (*q == '\0') + return(r); + if (*p++ != *q++) + break; + } + q=targets[i]; + } + } + return((char *) NULL); +} + +typedef struct color_t { + int red, green, blue, opacity; +} color_t; + + +#define TransparentOpacity 255 +#define OpaqueOpacity 0 +#define BackgroundColor "#ff" + +static unsigned int QueryColorDatabase(const char *name, + color_t *color) +{ + int + blue, + green, + opacity, + red; + + register long + i; + + /* + Initialize color return value. + */ + memset(color,0,sizeof(color_t)); + color->opacity=TransparentOpacity; + if ((name == (char *) NULL) || (*name == '\0')) + name=BackgroundColor; + while (isspace((int) (*name))) + name++; + if (*name == '#') + { + char + c; + + long + n; + + green=0; + blue=0; + opacity=(-1); + name++; + for (n=0; isxdigit((int) name[n]); n++); + if ((n == 3) || (n == 6) || (n == 9) || (n == 12)) + { + /* + Parse RGB specification. + */ + n/=3; + do + { + red=green; + green=blue; + blue=0; + for (i=n-1; i >= 0; i--) + { + c=(*name++); + blue<<=4; + if ((c >= '0') && (c <= '9')) + blue|=c-'0'; + else + if ((c >= 'A') && (c <= 'F')) + blue|=c-('A'-10); + else + if ((c >= 'a') && (c <= 'f')) + blue|=c-('a'-10); + else + return(0); + } + } while (isxdigit((int) *name)); + } + else + if ((n != 4) && (n != 8) && (n != 16)) + return(0); + else + { + /* + Parse RGBA specification. + */ + n/=4; + do + { + red=green; + green=blue; + blue=opacity; + opacity=0; + for (i=n-1; i >= 0; i--) + { + c=(*name++); + opacity<<=4; + if ((c >= '0') && (c <= '9')) + opacity|=c-'0'; + else + if ((c >= 'A') && (c <= 'F')) + opacity|=c-('A'-10); + else + if ((c >= 'a') && (c <= 'f')) + opacity|=c-('a'-10); + else + return(0); + } + } while (isxdigit((int) *name)); + } + n<<=1; + color->red=red/(1<<n); + color->green=green/(1<<n); + color->blue=blue/(1<<n); + color->opacity=OpaqueOpacity; + if (opacity >= 0) color->opacity=opacity>>((1 << n)); + return(1); + } + return(1); +} + +#define EXE "tcxpm2rgb" +#define MAX_BUF 1024 + +void version(void) +{ + // print id string to stderr + fprintf(stderr, "%s (%s v%s) (C) 2003 Tilmann Bitterberg\n", + EXE, PACKAGE, VERSION); +} + + +static void usage(int status) +{ + version(); + + fprintf(stderr,"\n%s converts a XPM file to rgb24 format\n", EXE); + fprintf(stderr,"Usage: %s [options]\n", EXE); + + fprintf(stderr," -i name input file name [stdin]\n"); + fprintf(stderr," -o name output file name [stdout]\n"); + fprintf(stderr," -v print version\n"); + + exit(status); + +} + + +int main (int argc, char *argv[]) +{ + char linebuf[MAX_BUF], target[MAX_BUF], key[16]; + FILE *f, *o; + int width, height, colors, bwidth, n, j, linelen, x, y, ch; + char **clist, **keys; + char *p, *q, *line; + char *out = NULL, *d; + char *outfile = NULL, *infile=NULL; + color_t *colormap; + long sret; + + while ((ch = getopt(argc, argv, "i:o:vh?")) != -1) { + + switch (ch) { + + case 'i': + + if(optarg[0]=='-') usage(EXIT_FAILURE); + infile = optarg; + + break; + + case 'o': + + if(optarg[0]=='-') usage(EXIT_FAILURE); + outfile = optarg; + + break; + + case 'v': + version(); + exit(EXIT_SUCCESS); + break; + case '?': + case 'h': + default: + usage(EXIT_SUCCESS); + break; + + } + } + + if (infile) { + f = fopen(infile, "r"); + if (!f) { + tc_log_perror(EXE, "fopen infile"); + return 1; + } + } else + f = stdin; + + if (outfile) { + o = fopen(outfile, "w"); + if (!o) { + tc_log_perror(EXE, "fopen outfile"); + return 1; + } + } else + o = stdout; + + + if (!fgets(linebuf, MAX_BUF, f)) { + tc_log_error(EXE, "No more lines"); + return 1; + } + + if (strncmp ("/* XPM */", linebuf, 9) != 0) { + tc_log_error(EXE, "Not an xpm file 1 (%s)", linebuf); + return 1; + } + + if (!fgets(linebuf, MAX_BUF, f)) { + tc_log_error(EXE, "No more lines"); + return 1; + } + if (strncmp ("static char", linebuf, 11) != 0) { + tc_log_error(EXE, "Not an xpm file 2"); + return 1; + } + + fgets(linebuf, MAX_BUF, f); + n = sscanf(linebuf+1, "%d %d %d %d", &width, &height, &colors, &bwidth); + if (n != 4 || (bwidth > 2) || (width == 0) || (height == 0) || (colors == 0)) { + tc_log_error(EXE, "Error reading header"); + return 1; + } + //tc_log_info(EXE, "XPM Image: %dx%d; %d colors, %d byte wide", width, height, colors, bwidth); + + clist = tc_malloc(colors*sizeof(char *)); + + if (clist == (char **)NULL) { + tc_log_error(EXE, "Error malloc clist"); + return 1; + } + + // color lookup table + colormap = tc_malloc(colors*sizeof(color_t)); + + for (n=0; n<colors; n++) { + int len; + + if (!fgets(linebuf, MAX_BUF, f)) { + tc_log_error(EXE, "Error reading color table"); + return 1; + } + len=strlen(linebuf); + + clist[n] = tc_malloc(len); + memcpy(clist[n], linebuf+1, len-3); + clist[n][len-4] = '\0'; + //tc_log_msg(EXE, "[%d] : %s|", n, clist[n]); + } + + keys = tc_malloc(colors*sizeof(char *)); + + for (j=0; j<colors; j++) { + p = clist[j]; + + keys[j] = tc_malloc(bwidth+1); // a bit stupid since bwidth is usually just 1 or 2 + keys[j][bwidth]='\0'; + + sret = strlcpy(keys[j], p, bwidth+1); + tc_test_string(__FILE__, __LINE__, bwidth+1, sret, errno); + + sret = strlcpy(target, "gray", sizeof(target)); + tc_test_string(__FILE__, __LINE__, sizeof(target), sret, errno); + + q = ParseColor (p+bwidth); + if (q != (char *) NULL) + { + while (!isspace((int) (*q)) && (*q != '\0')) + q++; + (void) strncpy(target,q,sizeof(target)-1); + q=ParseColor(target); + if (q != (char *) NULL) + *q='\0'; + } + QueryColorDatabase(target, &colormap[j]); + } + + if (j < colors) { + tc_log_error(EXE, "Corrupt XPM image file"); + return 1; + } + memset (key, '\0', 16); + + linelen = width * bwidth + 16; + line = tc_malloc(linelen); + + out = tc_malloc (width*height*3); + if (!out || !line) { + tc_log_error(EXE, "Error malloc line"); + return 1; + } + + d = out; + j=0; + for (y = 0; y<height; y++) { + int len; + + if (!fgets(line, linelen, f)) { + tc_log_error(EXE, "Error reading line %d", y); + return 1; + } + len = strlen(line); + p = line+1; + p[len-4]='\0'; + + for (x = 0; x<width; x++) { + + strncpy(key,p,bwidth); + + // can anything be slower? + if (strcmp(key,keys[j]) != 0) + for (j=0; j < colors; j++) + if (strcmp(key,keys[j]) == 0) + break; + + *d++ = colormap[j].red&0xff; + *d++ = colormap[j].green&0xff; + *d++ = colormap[j].blue&0xff; + p+=bwidth; + + } + } + + if ( (n = fwrite (out, width*height*3, 1, o))<0) { + tc_log_error(EXE, "fwrite failed (should = %d, have = %d)", width*height*3, n); + return 1; + } + + fclose(o); + + //tc_log_msg(EXE, "Wrote %s", outfile); + + free(out); + free(line); + for (n=0; n<colors; n++) { + free(clist[n]); + free(keys[n]); + } + free(clist); + free(keys); + free(colormap); + + // read }; + if (!fgets(linebuf, MAX_BUF, f)) { + tc_log_perror(EXE, "fgets header"); + return 1; + } + + + + fclose (f); + + return 0; +} |
