home *** CD-ROM | disk | FTP | other *** search
Wrap
/* * Don't use capstdio and ?capalloc since will really be external from * doslynx (TurboVision) code. Every allocation is clean, * and display is erased once doslynx will start back up. */ #include"capalloc.h" #include<string.h> #include <graphics.h> #include <stdlib.h> #include <conio.h> #include <stdio.h> #include <math.h> #ifdef SVGA #include "svga256.h" #endif /* SVGA */ #include "image.h" #define FALSE 0 #define TRUE 1 #define pm_message printf #define pm_error printf char *image_mode_names[] = { "CGA (640x200x2)", "EGA (640x350x16)", "Hercules (720x348x2)", "VGA (640x480x16)", "VGA (320x200x256)" #ifdef SVGA , "SVGA (640x480x256)", "SVGA (800x600x256)", "SVGA (1024x768x256)" #endif /* SVGA */ }; static int gif_setup(image_modes mode); static void gif_shutdown(void); static int colorsavail; static float gif_aspect; static float mode_aspect; static int *xvector; static int *yvector; #ifdef SVGA static int svga_mode_choice; #endif /* SVGA */ #ifdef SVGA int huge DetectVGA256(); static DacPalette256 pal256; #endif /* SVGA */ typedef struct { int r, g, b; } rgb; #define MYMAXCOLORS 256 static rgb *ctable; static int psettable = 0; static void setp(int id, rgb v); static int ctotal = 0; static int *vtoc; #ifdef SVGA static int svga_flag = 0; #endif /* SVGA */ typedef struct { unsigned int Width; unsigned int Height; unsigned char ColorMap[3][MYMAXCOLORS]; unsigned int BitPixel; unsigned int ColorResolution; unsigned int Background; unsigned int AspectRatio; } GifScreenType; /* We'll have to malloc this sucker to keep DOS memory schemes happy */ static GifScreenType *GifScreen_p; /* Alias to make the GIF code happy */ #define GifScreen (*GifScreen_p) static long *hist; static int *foundcolors; static int foundtotal = 0; static char *bgi_path = 0; static char *bgi_default = ""; static int gif_setup(image_modes mode) { int gdriver, gmode, errorcode; int xasp, yasp; struct palettetype pal; int i; #ifdef SVGA svga_flag = 0; #endif /* SVGA */ registerfarbgidriver(EGAVGA_driver_far); registerfarbgidriver(Herc_driver_far); registerfarbgidriver(CGA_driver_far); ctable = (rgb*) malloc(sizeof(rgb) * (size_t)MYMAXCOLORS); if(ctable == NULL) { pm_error("Out of memory.\n"); return(-1); } vtoc = (int*) malloc(sizeof(int) * (size_t)MYMAXCOLORS); if(vtoc == NULL) { free(ctable); ctable = NULL; pm_error("Out of memory.\n"); return(-1); } hist = (long*) malloc(sizeof(long) * (size_t)MYMAXCOLORS); if(hist == NULL) { free(ctable); ctable = NULL; free(vtoc); vtoc = NULL; pm_error("Out of memory.\n"); return(-1); } foundcolors = (int*) malloc(sizeof(int) * (size_t)MYMAXCOLORS); if(foundcolors == NULL) { free(ctable); ctable = NULL; free(vtoc); vtoc = NULL; free(hist); hist = NULL; pm_error("Out of memory.\n"); return(-1); } GifScreen_p = (GifScreenType*) malloc(sizeof(GifScreenType)); foundcolors = (int*) malloc(sizeof(int) * (size_t)MYMAXCOLORS); if(foundcolors == NULL) { free(ctable); ctable = NULL; free(vtoc); vtoc = NULL; free(hist); hist = NULL; free(foundcolors); foundcolors = NULL; pm_error("Out of memory.\n"); return(-1); } switch(mode) { case image_mode_cga: gdriver = CGA; gmode = CGAHI; break; case image_mode_herc: detectgraph(&gdriver, &gmode); if (gdriver != HERCMONO) { printf("You do not have a Hercules graphics card installed\n"); printf("(or that is not the preferred mode of your graphics card).\n"); printf("Try CGA, EGA or VGA.\n"); free(ctable); ctable = NULL; free(vtoc); vtoc = NULL; free(hist); hist = NULL; free(foundcolors); foundcolors = NULL; free(GifScreen_p); GifScreen_p = NULL; return -1; } gdriver = HERCMONO; gmode = HERCMONOHI; break; case image_mode_ega: gdriver = EGA; gmode = EGAHI; break; case image_mode_vga_640x480x16: gdriver = VGA; gmode = VGAHI; break; #ifdef SVGA case image_mode_vga_320x200x256: svga_flag = 1; gdriver = DETECT; gmode = SVGA320x200x256; break; case image_mode_svga_640x480x256: svga_flag = 1; gdriver = DETECT; gmode = SVGA640x480x256; break; case image_mode_svga_800x600x256: svga_flag = 1; gdriver = DETECT; gmode = SVGA800x600x256; break; case image_mode_svga_1024x768x256: svga_flag = 1; gdriver = DETECT; gmode = SVGA1024x768x256; break; #endif /* SVGA */ default: gdriver = DETECT; break; } #ifdef SVGA if (svga_flag) { installuserdriver("Svga256",DetectVGA256); registerfarbgidriver(Svga256_fdriver); svga_mode_choice = gmode; } #endif /* SVGA */ if (!bgi_path) { bgi_path = getenv("BGI_PATH"); } if (!bgi_path) { bgi_path = bgi_default; } initgraph(&gdriver, &gmode, bgi_path); errorcode = graphresult(); /* an error occurred */ if (errorcode != grOk) { printf("Graphics error: %s\n", grapherrormsg(errorcode)); printf("(Perhaps the .BGI drivers are not in the current directory\n"); printf("and you have not set BGI_PATH to point to them.)\n"); free(ctable); ctable = NULL; free(vtoc); vtoc = NULL; free(hist); hist = NULL; free(foundcolors); foundcolors = NULL; free(GifScreen_p); GifScreen_p = NULL; return -1; } getaspectratio(&xasp, &yasp); colorsavail = getmaxcolor() + 1; if (colorsavail == 2) { ctable[0].r = 0x0; ctable[0].g = 0x0; ctable[0].b = 0x0; ctable[1].r = 0xFF; ctable[1].g = 0xFF; ctable[1].b = 0xFF; setp(0, ctable[0]); setp(1, ctable[1]); } else { psettable = 1; } ctotal = 0; for (i=0; (i<MYMAXCOLORS); i++) { vtoc[i] = -1; } mode_aspect = (float)yasp / (float)xasp; pal.size = colorsavail; for (i=0; (i<colorsavail); i++) { pal.colors[i] = i; } setallpalette(&pal); return 0; } static void gif_shutdown(void) { closegraph(); free(ctable); free(vtoc); free(hist); free(foundcolors); free(GifScreen_p); } static int ReadGIF ( FILE *fd, int imageNumber ); /* * To get rid of the static memory hog this code has! */ #define MAX_LWZ_BITS 12 int *ip_table0 = NULL; int *ip_table1 = NULL; int *ip_stack = NULL; signed short int image_viewer(const char *fname, image_modes mode) { FILE *in; if (gif_setup(mode) != 0) { fprintf(stderr, "Graphics mode %s not available.\n", image_mode_names[mode]); fprintf(stderr, "Press any key:\n"); getch(); return -1; } in = fopen(fname, "rb"); if (!in) { fprintf(stderr, "File %s not found\n", fname); fprintf(stderr, "Press any key:\n"); getch(); gif_shutdown(); return -1; } /* * Allocate the static memory the code used to have off of the * heap. If unable, return an error, -1. * The memory allocated here will be realeased at the return * of this function. */ if(ip_table0 == NULL || ip_table1 == NULL || ip_stack == NULL) { ip_table0 = (int *)calloc((size_t)2, (size_t)((size_t)1 << (size_t)MAX_LWZ_BITS) * sizeof(int)); ip_table1 = ip_table0 + (size_t)((size_t)1 << (size_t)MAX_LWZ_BITS); ip_stack = (int *)calloc((size_t)2, (size_t)((size_t)1 << (size_t)MAX_LWZ_BITS) * sizeof(int)); if(ip_table0 == NULL || ip_table1 == NULL || ip_stack == NULL) { pm_error("Out of memory.\n"); gif_shutdown(); return(-1); } } if (ReadGIF(in, 1) != 0) { fprintf(stderr, "\n"); fprintf(stderr, "Press any key:\n"); getch(); gif_shutdown(); free(ip_table0); free(ip_stack); ip_table0 = ip_table1 = ip_stack = NULL; return -1; } getch(); gif_shutdown(); free(ip_table0); free(ip_stack); ip_table0 = ip_table1 = ip_stack = NULL; return 0; } static void setp(int id, rgb v) { #ifdef SVGA if (svga_flag) { pal256[id][0] = v.r >> 2; pal256[id][1] = v.g >> 2; pal256[id][2] = v.b >> 2; } else { #endif /* SVGA */ setrgbpalette(id, v.r >> 2, v.g >> 2, v.b >> 2); #ifdef SVGA } #endif /* SVGA */ } /* +-------------------------------------------------------------------+ */ /* | Copyright 1990, David Koblas. | */ /* | 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. | */ /* +-------------------------------------------------------------------+ */ #define CM_RED 0 #define CM_GREEN 1 #define CM_BLUE 2 #define INTERLACE 0x40 #define LOCALCOLORMAP 0x80 #define BitSet(byte, bit) (((byte) & (bit)) == (bit)) #define ReadOK(file,buffer,len) (fread(buffer, len, 1, file) != 0) #define LM_to_uint(a,b) (((b)<<8)|(a)) struct { int transparent; int delayTime; int inputFlag; int disposal; } Gif89 = { -1, -1, -1, 0 }; int verbose; int showComment; static int ReadColorMap ( FILE *fd, int number, unsigned char buffer[3][MYMAXCOLORS] ); static int DoExtension ( FILE *fd, int label ); static int GetDataBlock ( FILE *fd, unsigned char *buf ); static int GetCode ( FILE *fd, int code_size, int flag ); static int LWZReadByte ( FILE *fd, int flag, int input_code_size ); static int DisplayImage ( FILE *fd, int len, int height, int maxcolors, unsigned char cmap[3][MYMAXCOLORS], int interlace, int ignore ); static int HistImage ( FILE *fd, int len, int height, unsigned char cmap[3][MYMAXCOLORS], int interlace, int ignore, long hist[MYMAXCOLORS], int *mc_color); static int verbose = FALSE; static int showComment = FALSE; int mc_color; static int ReadGIF(fd, imageNumber) FILE *fd; int imageNumber; { int maxcolors; unsigned char buf[16]; unsigned char c; unsigned char localColorMap[3][MYMAXCOLORS]; int useGlobalColormap; int bitPixel; int imageCount = 0; char version[4]; if (! ReadOK(fd,buf,6)) { pm_error("error reading magic number" ); return -1; } if (strncmp(buf,"GIF",3) != 0) { pm_error("not a GIF file" ); return -1; } strncpy(version, buf + 3, 3); version[3] = '\0'; if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0)) { pm_error("bad version number, not '87a' or '89a'" ); return -1; } if (! ReadOK(fd,buf,7)) { pm_error("failed to read screen descriptor" ); return -1; } GifScreen.Width = LM_to_uint(buf[0],buf[1]); GifScreen.Height = LM_to_uint(buf[2],buf[3]); GifScreen.BitPixel = 2<<(buf[4]&0x07); GifScreen.ColorResolution = (((buf[4]&0x70)>>3)+1); GifScreen.Background = buf[5]; GifScreen.AspectRatio = buf[6]; maxcolors = GifScreen.BitPixel; if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */ if (ReadColorMap(fd,GifScreen.BitPixel,GifScreen.ColorMap)) { pm_error("error reading global colormap" ); return -1; } } if (GifScreen.AspectRatio != 0 && GifScreen.AspectRatio != 49) { float r; r = ( (float) GifScreen.AspectRatio + 15.0 ) / 64.0; gif_aspect = r; } for (;;) { if (! ReadOK(fd,&c,1)) { pm_error("EOF / read error on image data" ); return -1; } if (c == ';') { /* GIF terminator */ if (imageCount < imageNumber) { pm_error("only %d image%s found in file", imageCount, imageCount>1?"s":"" ); return -1; } return 0; } if (c == '!') { /* Extension */ if (! ReadOK(fd,&c,1)) { pm_error("OF / read error on extension function code"); return -1; } DoExtension(fd, c); continue; } if (c != ',') { /* Not a valid start character */ pm_message("bogus character 0x%02x, ignoring", (int) c ); continue; } ++imageCount; if (! ReadOK(fd,buf,9)) { pm_error("couldn't read left/top/width/height"); return -1; } useGlobalColormap = ! BitSet(buf[8], LOCALCOLORMAP); bitPixel = 1<<((buf[8]&0x07)+1); if (! useGlobalColormap) { if (ReadColorMap(fd, bitPixel, localColorMap)) { pm_error("error reading local colormap" ); return -1; } maxcolors = bitPixel; DisplayImage(fd, LM_to_uint(buf[4],buf[5]), LM_to_uint(buf[6],buf[7]), maxcolors, localColorMap, BitSet(buf[8], INTERLACE), imageCount != imageNumber); } else { DisplayImage(fd, LM_to_uint(buf[4],buf[5]), LM_to_uint(buf[6],buf[7]), maxcolors, GifScreen.ColorMap, BitSet(buf[8], INTERLACE), imageCount != imageNumber); } } return 0; } static int ReadColorMap(fd,number,buffer) FILE *fd; int number; unsigned char buffer[3][MYMAXCOLORS]; { int i; unsigned char rgb[3]; for (i = 0; i < number; ++i) { if (! ReadOK(fd, rgb, sizeof(rgb))) { pm_error("bad colormap" ); return -1; } buffer[CM_RED][i] = rgb[0] ; buffer[CM_GREEN][i] = rgb[1] ; buffer[CM_BLUE][i] = rgb[2] ; } return 0; } static int DoExtension(fd, label) FILE *fd; int label; { static char buf[256]; char *str; switch (label) { case 0x01: /* Plain Text Extension */ str = "Plain Text Extension"; #ifdef notdef if (GetDataBlock(fd, (unsigned char*) buf) == 0) ; lpos = LM_to_uint(buf[0], buf[1]); tpos = LM_to_uint(buf[2], buf[3]); width = LM_to_uint(buf[4], buf[5]); height = LM_to_uint(buf[6], buf[7]); cellw = buf[8]; cellh = buf[9]; foreground = buf[10]; background = buf[11]; while (GetDataBlock(fd, (unsigned char*) buf) != 0) { PPM_ASSIGN(image[ypos][xpos], cmap[CM_RED][v], cmap[CM_GREEN][v], cmap[CM_BLUE][v]); ++index; } return FALSE; #else break; #endif case 0xff: /* Application Extension */ str = "Application Extension"; break; case 0xfe: /* Comment Extension */ str = "Comment Extension"; while (GetDataBlock(fd, (unsigned char*) buf) != 0) { if (showComment) pm_message("gif comment: %s", buf ); } return FALSE; case 0xf9: /* Graphic Control Extension */ str = "Graphic Control Extension"; (void) GetDataBlock(fd, (unsigned char*) buf); Gif89.disposal = (buf[0] >> 2) & 0x7; Gif89.inputFlag = (buf[0] >> 1) & 0x1; Gif89.delayTime = LM_to_uint(buf[1],buf[2]); if ((buf[0] & 0x1) != 0) Gif89.transparent = buf[3]; while (GetDataBlock(fd, (unsigned char*) buf) != 0) ; return FALSE; default: str = buf; sprintf(buf, "UNKNOWN (0x%02x)", label); break; } pm_message("got a '%s' extension", str ); while (GetDataBlock(fd, (unsigned char*) buf) != 0) ; return FALSE; } int ZeroDataBlock = FALSE; static int GetDataBlock(fd, buf) FILE *fd; unsigned char *buf; { unsigned char count; if (! ReadOK(fd,&count,1)) { pm_message("error in getting DataBlock size" ); return -1; } ZeroDataBlock = count == 0; if ((count != 0) && (! ReadOK(fd, buf, count))) { pm_message("error in reading DataBlock" ); return -1; } return count; } static int GetCode(fd, code_size, flag) FILE *fd; int code_size; int flag; { static unsigned char buf[280]; static int curbit, lastbit, done, last_byte; int i, j, ret; unsigned char count; if (flag) { curbit = 0; lastbit = 0; done = FALSE; return 0; } if ( (curbit+code_size) >= lastbit) { if (done) { if (curbit >= lastbit) pm_error("ran off the end of my bits" ); return -1; } buf[0] = buf[last_byte-2]; buf[1] = buf[last_byte-1]; if ((count = GetDataBlock(fd, &buf[2])) == 0) done = TRUE; last_byte = 2 + count; curbit = (curbit - lastbit) + 16; lastbit = (2+count)*8 ; } ret = 0; for (i = curbit, j = 0; j < code_size; ++i, ++j) ret |= ((buf[ i / 8 ] & (1 << (i % 8))) != 0) << j; curbit += code_size; return ret; } static int LWZReadByte(fd, flag, input_code_size) FILE *fd; int flag; int input_code_size; { static int fresh = FALSE; int code, incode; static int code_size, set_code_size; static int max_code, max_code_size; static int firstcode, oldcode; static int clear_code, end_code; static int *table[2]; static int *stack, *sp; register int i; /* * Assign in the used to be static area as now pointers. */ table[0] = ip_table1; table[1] = ip_table0; stack = ip_stack; if (flag) { set_code_size = input_code_size; code_size = set_code_size+1; clear_code = 1 << set_code_size ; end_code = clear_code + 1; max_code_size = 2*clear_code; max_code = clear_code+2; GetCode(fd, 0, TRUE); fresh = TRUE; for (i = 0; i < clear_code; ++i) { table[0][i] = 0; table[1][i] = i; } table[1][0] = 0; for (; i < (1<<MAX_LWZ_BITS); ++i) { table[0][i] = 0; } sp = stack; return 0; } else if (fresh) { fresh = FALSE; do { firstcode = oldcode = GetCode(fd, code_size, FALSE); } while (firstcode == clear_code); return firstcode; } if (sp > stack) { return *--sp; } while ((code = GetCode(fd, code_size, FALSE)) >= 0) { if (code == clear_code) { for (i = 0; i < clear_code; ++i) { table[0][i] = 0; table[1][i] = i; } for (; i < (1<<MAX_LWZ_BITS); ++i) table[0][i] = table[1][i] = 0; code_size = set_code_size+1; max_code_size = 2*clear_code; max_code = clear_code+2; sp = stack; firstcode = oldcode = GetCode(fd, code_size, FALSE); return firstcode; } else if (code == end_code) { int count; unsigned char buf[260]; if (ZeroDataBlock) { return -2; } while ((count = GetDataBlock(fd, buf)) > 0) ; if (count != 0) pm_message("missing EOD in data stream (common occurence)"); return -2; } incode = code; if (code >= max_code) { *sp++ = firstcode; code = oldcode; } while (code >= clear_code) { *sp++ = table[1][code]; if (code == table[0][code]) pm_error("circular table entry BIG ERROR"); code = table[0][code]; } *sp++ = firstcode = table[1][code]; if ((code = max_code) <(1<<MAX_LWZ_BITS)) { table[0][code] = oldcode; table[1][code] = firstcode; ++max_code; if ((max_code >= max_code_size) && (max_code_size < (1<<MAX_LWZ_BITS))) { max_code_size *= 2; ++code_size; } } oldcode = incode; if (sp > stack) { return *--sp; } } return code; } int cmpcolors(const void *v1, const void *v2) { int cid1 = *(int*)v1; int cid2 = *(int*)v2; return (hist[cid1] < hist[cid2]); } int color_d = 0; int *pflags; static int DisplayImage(fd, len, height, maxcolors, cmap, interlace, ignore) FILE *fd; int len, height; int maxcolors; unsigned char cmap[3][MYMAXCOLORS]; int interlace, ignore; { unsigned char c; int r, g, b; int all_colors = 0; int dither_colors = 0; int ra, ga, ba; int v; int xpos = 0, ypos = 0, pass = 0; int vxpos = 0, vypos = 0; long fpos; int i; float lastacc; float xacc = 0.0; float yacc = 0.0; float sf = 1.0; int xs; int ys; int vydup = 1; fpos = ftell(fd); foundtotal = 0; if (maxcolors <= colorsavail) { for (i=0; (i<maxcolors); i++) { foundcolors[i] = i; } foundtotal = maxcolors; } else { printf("Counting colors...\n"); HistImage(fd, len, height, cmap, interlace, ignore, hist, &mc_color); cleardevice(); } if (foundtotal <= colorsavail) { all_colors = 1; for (i=0; (i<foundtotal); i++) { vtoc[foundcolors[i]] = i; ctable[i].r = cmap[0][foundcolors[i]]; ctable[i].g = cmap[1][foundcolors[i]]; ctable[i].b = cmap[2][foundcolors[i]]; setp(i, ctable[i]); } } else if (colorsavail >= 8) { i = 0; dither_colors = 1; for (r = 0; (r < 2); r++) { for (g = 0; (g < 2); g++) { for (b = 0; (b < 2); b++) { ctable[i].r = r * 0xff; ctable[i].g = g * 0xff; ctable[i].b = b * 0xff; setp(i, ctable[i]); i++; } } } if (colorsavail >= 16) { /* Half-intensity colors */ dither_colors = 2; for (r = 0; (r < 2); r++) { for (g = 0; (g < 2); g++) { for (b = 0; (b < 2); b++) { ctable[i].r = r * 0x80; ctable[i].g = g * 0x80; ctable[i].b = b * 0x80; setp(i, ctable[i]); i++; } } } } } if (!all_colors) { /* Blow it up to give the dithering a better chance; it'll be knocked down below if this makes it too big */ sf *= 3; } if (mode_aspect > 1.0) { /* Blow it up to avoid loss of pixels on y axis; again, code below will knock this back down if necessary */ sf *= mode_aspect; } xs = getmaxx()+1; ys = getmaxy()+1; xvector = (int *) malloc(sizeof(int) * (size_t)((size_t)len+(size_t)2)); if (!xvector) { pm_error("Out of memory\n"); return -1; } yvector = (int *) malloc(sizeof(int) * (size_t)((size_t)height+(size_t)2)); if(!yvector) { pm_error("Out of memory\n"); return(-1); } pflags = (int *) malloc(sizeof(int) * (size_t)ys); if(!pflags) { pm_error("Out of memory\n"); return(-1); } for (i=0; (i<ys); i++) { pflags[i] = 0; } if (len*sf > xs) { sf = (float)xs / len; } if (height*sf > ys * mode_aspect) { sf = (float)ys * mode_aspect / height; } lastacc = 0; for (i=0; (i<len); i++) { float diff; xacc = sf*(i+1); diff = floor(xacc)-floor(lastacc); xvector[i] = (int) diff; lastacc = xacc; } lastacc = 0; for (i=0; (i<height); i++) { float diff; yacc = sf*(i+1)/mode_aspect; diff = floor(yacc)-floor(lastacc); yvector[i] = (int) diff; lastacc = yacc; } #ifdef SVGA if (svga_flag) { setvgapalette256(&pal256); } #endif /* SVGA */ fseek(fd, fpos, SEEK_SET); /* ** Initialize the Compression routines */ if (! ReadOK(fd,&c,1)) { pm_error("EOF / read error on image data" ); return -1; } if (LWZReadByte(fd, TRUE, c) < 0) { pm_error("error reading image" ); return -1; } /* ** If this is an "uninteresting picture" ignore it. */ if (ignore) { if (verbose) pm_message("skipping image..." ); while (LWZReadByte(fd, FALSE, c) >= 0) ; return 0; } if (verbose) pm_message("reading %d by %d%s GIF image", len, height, interlace ? " interlaced" : "" ); ra = random(256); ga = random(256); ba = random(256); vydup = 1; while ((v = LWZReadByte(fd,FALSE,c)) >= 0 ) { int y; if (yvector[ypos] && (!pflags[vypos])) { for (i=0; (i<xvector[xpos]); i++) { if (all_colors) { int y; for (y=vypos; (y < vypos+vydup); y++) { putpixel(vxpos, y, vtoc[v]); } vxpos++; } else if (dither_colors) { int high; int shift = 0; int rf, gf, bf; rf = cmap[CM_RED][v]; gf = cmap[CM_GREEN][v]; bf = cmap[CM_BLUE][v]; ra += rf; ga += gf; ba += bf; high = max(max(rf, gf), bf); if ((dither_colors == 2) && (high <= 0x80)) { shift = 8; if (ra >= 128) { ra -= 128; r = 4; } else { r = 0; } if (ga >= 128) { ga -= 128; g = 2; } else { g = 0; } if (ba >= 128) { ba -= 128; b = 1; } else { b = 0; } } else { if (ra >= 255) { ra -= 255; r = 4; } else { r = 0; } if (ga >= 255) { ga -= 255; g = 2; } else { g = 0; } if (ba >= 255) { ba -= 255; b = 1; } else { b = 0; } } for (y=vypos; (y < vypos+vydup); y++) { putpixel(vxpos, y, color_d+r+g+b+shift); } vxpos++; } else { /* Dither black and white */ int l = cmap[CM_RED][v] + cmap[CM_GREEN][v] + cmap[CM_BLUE][v]; l /= 3; ra += l; if (ra >= 255) { ra -= 255; r = 1; } else { r = 0; } for (y=vypos; (y < vypos+vydup); y++) { putpixel(vxpos, y, r); } vxpos++; } } } ++xpos; if (xpos == len) { vxpos = 0; xpos = 0; if (yvector[ypos]) { pflags[vypos] = 1; } ra = random(256); ga = random(256); ba = random(256); if (interlace) { switch (pass) { case 0: case 1: ypos += 8; break; case 2: ypos += 4; break; case 3: ypos += 2; break; } if (ypos >= height) { ++pass; switch (pass) { case 1: ypos = 4; break; case 2: ypos = 2; break; case 3: ypos = 1; break; default: goto fini; } } } else { ++ypos; } vypos = ypos * sf / mode_aspect; /* Fudge to avoid inevitable streaks */ vydup = yvector[ypos]+1; } if (ypos >= height) break; } fini: if (LWZReadByte(fd,FALSE,c)>=0) pm_message("too much input data, ignoring extra..."); free(xvector); free(yvector); free(pflags); return 0; } static int HistImage(fd, len, height, cmap, interlace, ignore, hist, mc_color) FILE *fd; int len, height; unsigned char cmap[3][MYMAXCOLORS]; int interlace, ignore; long hist[MYMAXCOLORS]; int *mc_color; { unsigned char c; int v; int i; for (i=0; (i<MYMAXCOLORS); i++) { hist[i] = 0; } /* ** Initialize the Compression routines */ if (! ReadOK(fd,&c,1)) { pm_error("EOF / read error on image data" ); return -1; } if (LWZReadByte(fd, TRUE, c) < 0) { pm_error("error reading image" ); return -1; } /* ** If this is an "uninteresting picture" ignore it. */ if (ignore) { if (verbose) pm_message("skipping image..." ); while (LWZReadByte(fd, FALSE, c) >= 0) ; return 0; } if (verbose) pm_message("reading %d by %d%s GIF image", len, height, interlace ? " interlaced" : "" ); while ((v = LWZReadByte(fd,FALSE,c)) >= 0 ) { if (!hist[v]) { foundcolors[foundtotal++] = v; } hist[v]++; if (hist[v] > hist[*mc_color]) { *mc_color = v; } } return 0; } #ifdef SVGA int huge DetectVGA256() { return svga_mode_choice; } #endif /* SVGA */