📄 xgprintgif.c
字号:
#ifdef XPMENABLED/* xpmtoppm.c - read an X11 pixmap file and produce a portable pixmap**** Copyright (C) 1991 by Jef Poskanzer.**** Permission to use, copy, modify, and distribute this software and its** documentation for any purpose and without fee is hereby granted, provided** that the above copyright notice appear in all copies and that both that** copyright notice and this permission notice appear in supporting** documentation. This software is provided "as is" without express or** implied warranty.**** Upgraded to support XPM version 3 by** Arnaud Le Hors (lehors@mirsa.inria.fr)** Tue Apr 9 1991**** Rainer Sinkwitz sinkwitz@ifi.unizh.ch - 21 Nov 91:** - Bug fix, no advance of read ptr, would not read ** colors like "ac c black" because it would find ** the "c" of "ac" and then had problems with "c"** as color.** ** - Now understands multword X11 color names** ** - Now reads multiple color keys. Takes the color** of the hightest available key. Lines no longer need** to begin with key 'c'.** ** - expanded line buffer to from 500 to 2048 for bigger files*/#include "xgprintgif.h"#include <X11/xpm.h>#include <ctype.h>#include <string.h>/*******************************************************************//*******************************************************************/#define BITS 12#define HSIZE 5003 /* 80% occupancy */#define TRUE 1#define FALSE 0#define NKEYS 5#define MAXCOLORS 256#define MAX_LINE 2048#define HASH_SIZE 20023#define ppm_hashpixel(p) ( ( ( (long) PPM_GETR(p) * 33023 + (long) PPM_GETG(p) * 30013 + (long) PPM_GETB(p) * 27011 ) & 0x7fffffff ) % HASH_SIZE )#define ARGVAL() (*++(*argv) || (--argc && *++argv))#ifdef COMPATIBLE /* But wrong! */# define MAXCODE(n_bits) ((code_int) 1 << (n_bits) - 1)#else /*COMPATIBLE*/# define MAXCODE(n_bits) (((code_int) 1 << (n_bits)) - 1)#endif /*COMPATIBLE*/#define HashTabOf(i) htab[i]#define CodeTabOf(i) codetab[i]#define tab_prefixof(i) CodeTabOf(i)#define tab_suffixof(i) ((char_type*)(htab))[i]#define de_stack ((char_type*)&tab_suffixof((code_int)1<<BITS))/*******************************************************************/typedef int (* ifunptr)();typedef int code_int;#ifdef NO_UCHARtypedef char char_type;#else /*NO_UCHAR*/typedef unsigned char char_type;#endif /*NO_UCHAR*/#ifdef SIGNED_COMPARE_SLOWtypedef unsigned long int count_int;typedef unsigned short int count_short;#else /*SIGNED_COMPARE_SLOW*/typedef long int count_int;#endif /*SIGNED_COMPARE_SLOW*//*******************************************************************/static int colorstobpp ( int colors );static int GetPixel ( int x, int y );static void BumpPixel ( void );static int GIFNextPixel ( ifunptr getpixel );static void GIFEncode ( FILE* fp, int GWidth, int GHeight, int GInterlace, int Background, int BitsPerPixel, int Red[], int Green[], int Blue[], ifunptr GetPixel );static void Putword ( int w, FILE* fp );static void compress ( int init_bits, FILE* outfile, ifunptr ReadValue );static void output ( code_int code );static void cl_block ( void );static void cl_hash ( count_int hsize );static void char_init ( void );static void char_out ( int c );static void flush_char ( void );void ReadXPMFile(char **stream, int *widthP, int *heightP, int *ncolorsP, int *chars_per_pixelP, pixel **colorsP);void getline( char *line, int size, char **stream);void ToGif(char *stream, char *outFile);void XpmToGif(char **xpmData, char *outFile);int ppm_getint(char *stream);/*******************************************************************/char *colorKeys[] = { "s", "m", "g4", "g", "c" };int read_index;int write_index;pixval ppm_pbmmaxval;pixel** pixels;colorhash_table cht;int Width, Height;int curx, cury;long CountDown;int Pass = 0;int Interlace;int n_bits; /* number of bits/code */int maxbits; /* user settable max # bits/code */code_int maxcode; /* maximum code, given n_bits */code_int maxmaxcode; /* should NEVER generate this code */count_int htab [HSIZE];unsigned short codetab [HSIZE];code_int hsize = HSIZE; /* for dynamic table sizing */code_int free_ent; /* first unused entry */int clear_flg;int offset;long int in_count; /* length of input */long int out_count; /* # of codes output (for debugging)*/int g_init_bits;FILE* g_outfile;int ClearCode;int EOFCode;unsigned long cur_accum;int cur_bits;int a_count;char accum[ 256 ];int getline_index;unsigned long masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };/**********************************************************************//**********************************************************************/void *my_malloc(size_t size) { void *temp = (void *)malloc(size); if (temp==NULL) { printf("Out of memory\n"); exit(-1); } return temp;}void *my_realloc(void *old, size_t size) { void *temp = (void *)realloc(old, size); if (temp==NULL) { printf("Out of memory\n"); exit(-1); } return temp;}void ppm_freecolorhist( colorhist_vector chv ) { free( chv );}void ppm_freecolorhash( colorhash_table cht ) { int i; colorhist_list chl, chlnext; if (cht!=NULL) { for ( i = 0; i < HASH_SIZE; ++i ) for ( chl = cht[i]; chl != (colorhist_list) 0; chl = chlnext ) { chlnext = chl->next; free( chl ); } free( cht ); }}colorhash_table ppm_alloccolorhash() { colorhash_table cht; int i; cht = (colorhash_table) my_malloc( HASH_SIZE * sizeof(colorhist_list) ); for ( i = 0; i < HASH_SIZE; ++i ) cht[i] = (colorhist_list) 0; return cht;}colorhash_table ppm_computecolorhash(pixel** pixels, int cols, int rows, int maxcolors, int* colorsP) { colorhash_table cht = NULL; register pixel* pP; colorhist_list chl; int col, row, hash; cht = ppm_alloccolorhash( ); *colorsP = 0; /* Go through the entire image, building a hash table of colors. */ for ( row = 0; row < rows; ++row ) for ( col = 0, pP = pixels[row]; col < cols; ++col, ++pP ) { hash = ppm_hashpixel( *pP ); for ( chl = cht[hash]; chl != (colorhist_list) 0; chl = chl->next ) if ( PPM_EQUAL( chl->ch.color, *pP ) ) break; if ( chl != (colorhist_list) 0 ) ++(chl->ch.value); else { if ( ++(*colorsP) > maxcolors ) { ppm_freecolorhash( cht ); return (colorhash_table) 0; } chl = (colorhist_list) my_malloc( sizeof(struct colorhist_list_item) ); chl->ch.color = *pP; chl->ch.value = 1; chl->next = cht[hash]; cht[hash] = chl; } } return cht;}int ppm_lookupcolor( colorhash_table cht, pixel* colorP) { int hash; colorhist_list chl; hash = ppm_hashpixel( *colorP ); for ( chl = cht[hash]; chl != (colorhist_list) 0; chl = chl->next ) if ( PPM_EQUAL( chl->ch.color, *colorP ) ) return chl->ch.value; return -1;}colorhash_table ppm_colorhisttocolorhash( colorhist_vector chv, int colors) { colorhash_table cht; int i, hash; pixel color; colorhist_list chl; cht = ppm_alloccolorhash( ); for ( i = 0; i < colors; ++i ) { color = chv[i].color; hash = ppm_hashpixel( color ); chl = (colorhist_list) my_malloc( sizeof(struct colorhist_list_item) ); chl->ch.color = color; chl->ch.value = i; chl->next = cht[hash]; cht[hash] = chl; } return cht;}colorhist_vector ppm_colorhashtocolorhist(colorhash_table cht, int maxcolors) { colorhist_vector chv; colorhist_list chl; int i, j; /* Now collate the hash table into a simple colorhist array. */ chv = (colorhist_vector) my_malloc( maxcolors * sizeof(struct colorhist_item) ); /* Loop through the hash table. */ j = 0; for ( i = 0; i < HASH_SIZE; ++i ) for ( chl = cht[i]; chl != (colorhist_list) 0; chl = chl->next ) { /* Add the new entry. */ chv[j] = chl->ch; ++j; } /* All done. */ return chv;}colorhist_vector ppm_computecolorhist( pixel** pixels, int cols, int rows, int maxcolors, int* colorsP) { colorhash_table cht = NULL; colorhist_vector chv; cht = ppm_computecolorhash( pixels, cols, rows, maxcolors, colorsP ); if ( cht == (colorhash_table) 0 ) return (colorhist_vector) 0; chv = ppm_colorhashtocolorhist( cht, maxcolors ); ppm_freecolorhash( cht ); return chv;}char *ppm_writeppminit( char *stream, int cols, int rows, pixval maxval, int forceplain ) { char temp[80]; if ( maxval <= 255 && ! forceplain ) sprintf(temp, "%c%c\n%d %d\n%d\n", PPM_MAGIC1, RPPM_MAGIC2, cols, rows, maxval ); else sprintf(temp, "%c%c\n%d %d\n%d\n", PPM_MAGIC1, PPM_MAGIC2, cols, rows, maxval ); write_index = strlen(temp); stream = (char*)my_malloc(sizeof(char)*(write_index+1)); strcpy(stream, temp); return stream;}char *pm_allocrow(int cols, int size) { register char* itrow; itrow = (char*) my_malloc( cols * size ); return itrow;}void putus( unsigned short n, char *stream) { if ( n >= 10 ) putus( n / 10, stream ); stream[write_index++] = n % 10 + '0';}void ppm_writeppmrowraw( char *stream, pixel* pixelrow, int cols, pixval maxval) { register int col; register pixel* pP; register pixval val; for ( col = 0, pP = pixelrow; col < cols; ++col, ++pP ) { val = PPM_GETR( *pP ); stream[write_index++] = val; val = PPM_GETG( *pP ); stream[write_index++] = val; val = PPM_GETB( *pP ); stream[write_index++] = val; }}void ppm_writeppmrowplain( char *stream, pixel* pixelrow, int cols, pixval maxval) { register int col, charcount; register pixel* pP; register pixval val; charcount = 0; for ( col = 0, pP = pixelrow; col < cols; ++col, ++pP ) { if ( charcount >= 65 ) { stream[write_index++] = '\n'; charcount = 0; } else if ( charcount > 0 ) { stream[write_index++] = ' '; stream[write_index++] = ' '; charcount += 2; } val = PPM_GETR( *pP ); putus( val, stream ); stream[write_index++] = ' '; val = PPM_GETG( *pP ); putus( val, stream ); stream[write_index++] = ' '; val = PPM_GETB( *pP ); putus( val, stream ); charcount += 11; } if ( charcount > 0 ) stream[write_index++] = '\n';}void ppm_writeppmrow( char *stream, pixel* pixelrow, int cols, pixval maxval, int forceplain ){ if ( maxval <= 255 && ! forceplain ) ppm_writeppmrowraw( stream, pixelrow, cols, maxval ); else ppm_writeppmrowplain( stream, pixelrow, cols, maxval );}long rgbnorm( long rgb, long lmaxval, int n, unsigned char* colorname) { switch ( n ) { case 1: if ( lmaxval != 15 ) rgb = rgb * lmaxval / 15; break; case 2: if ( lmaxval != 255 ) rgb = rgb * lmaxval / 255; break; case 3: if ( lmaxval != 4095 ) rgb = rgb * lmaxval / 4095; break; case 4: if ( lmaxval != 65535L ) rgb = rgb * lmaxval / 65535L; break; } return rgb;}pixel ppm_parsecolor( unsigned char* colorname, pixval maxval ) { int hexit[256], i; pixel p; long lmaxval, r, g, b; for ( i = 0; i < 256; ++i ) hexit[i] = 1234567890; hexit['0'] = 0; hexit['1'] = 1; hexit['2'] = 2; hexit['3'] = 3; hexit['4'] = 4; hexit['5'] = 5; hexit['6'] = 6; hexit['7'] = 7; hexit['8'] = 8; hexit['9'] = 9; hexit['a'] = hexit['A'] = 10; hexit['b'] = hexit['B'] = 11; hexit['c'] = hexit['C'] = 12; hexit['d'] = hexit['D'] = 13; hexit['e'] = hexit['E'] = 14; hexit['f'] = hexit['F'] = 15; lmaxval = maxval; if ( strncmp( (char *)colorname, "rgb:", 4 ) == 0 ) { /* It's a new-X11-style hexadecimal rgb specifier. */ unsigned char* cp; cp = colorname + 4; r = g = b = 0; for ( i = 0; *cp != '/'; ++i, ++cp ) r = r * 16 + hexit[*cp]; r = rgbnorm( r, lmaxval, i, colorname ); for ( i = 0, ++cp; *cp != '/'; ++i, ++cp ) g = g * 16 + hexit[*cp]; g = rgbnorm( g, lmaxval, i, colorname ); for ( i = 0, ++cp; *cp != '\0'; ++i, ++cp ) b = b * 16 + hexit[*cp]; b = rgbnorm( b, lmaxval, i, colorname ); } else if ( strncmp( (char *)colorname, "rgbi:", 5 ) == 0 ) { /* It's a new-X11-style decimal/float rgb specifier. */ float fr, fg, fb; sscanf((char *)colorname,"rgbi:%f/%f/%f",&fr,&fg,&fb); r = fr * lmaxval; g = fg * lmaxval; b = fb * lmaxval; } else if ( colorname[0] == '#' ) { /* It's an old-X11-style hexadecimal rgb specifier. */ switch ( strlen( (char *)colorname ) ) { case 4:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -