summaryrefslogtreecommitdiffstats
path: root/debian/transcode/transcode-1.1.7/import/tcxpm2rgb.c
diff options
context:
space:
mode:
Diffstat (limited to 'debian/transcode/transcode-1.1.7/import/tcxpm2rgb.c')
-rw-r--r--debian/transcode/transcode-1.1.7/import/tcxpm2rgb.c430
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;
+}