draw11.c

0000/***************************************************
0001 draw11.c
0002 replacement to draw1.c
0003***************************************************/
0004#include <stdio.h>
0005#include <stdlib.h>
0006#include <string.h>
0007#include <math.h>
0008#include <unistd.h>
0009#include "draw11.h"
0010#include "draw7.h"
0011#include "gcs1.h"
0012#define MAX 10000
0013#define PUSH(Y,XL,XR,DY)                             \
0014  if(sp<stack+MAX&&Y+(DY)>=0&&Y+(DY)<heightD)          \
0015    {sp->y=Y;sp->xl=XL;sp->xr=XR;sp->dy=DY;sp++;}
0016#define POP(Y,XL,XR,DY)                             \
0017  {sp--;Y=sp->y+(DY=sp->dy);XL=sp->xl;XR=sp->xr;}
0018
0019
0020int outbyte(int num,char *buf);
0021int flush();
0022
0023/*************** draw buffer ***********************/
0024
0025/**************** basic draw information ***********/
0026unsigned char* pD; // bitmap buffer
0027int depthD; // Mac standard 256 colors
0028int widthD; // picture size
0029int heightD;
0030int coloD; // current color for drawing
0031int xD; // current pen position
0032int yD;
0033int cliplD; // clip rect left
0034int cliprD;
0035int cliptD;
0036int clipbD;
0037
0038/**************** for polygon ***************/
0039unsigned char* poD; // bitmap buffer
0040int polyWidthD; // number of chars for one line of poD
0041int firstPtxD; // x value of first point. saved for closure
0042int firstPtyD;
0043int vertXD; // left-upper line crossings
0044int horiXD; // upper-left line crossings
0045int polyD; // 1 if polygon mode
0046int pxminD,pxmaxD,pyminD,pymaxD; // bounding rect
0047
0048/**************** for seed fill *************/
0049int seedD=0; // seed-fill mode
0050typedef struct{
0051  int y;
0052  int xl;
0053  int xr;
0054  int dy;
0055} Segment;
0056
0057/***************** for font ********************/
0058unsigned char* pfD; // font bitmap
0059int fontD; // font id (11,16,22)
0060int direcD; // direction of string 0:horiz 1:vert
0061int modeD; // current pen position is 0:left 1:right 2:center of string
0062int widthBytesD;
0063int fontBytesD;
0064int ascentD;
0065int descentD;
0066int fontWidthD;
0067int fontHeightD;
0068#include "font.c"
0069
0070/***************** for graph ********************/
0071int lgD,tgD,rgD,bgD;
0072double ldgD,tdgD,rdgD,bdgD;
0073int htD,hlD,vlD;
0074
0075/**************** output ***********************/
0076int widMin,widMax,heiMin,heiMax;
0077int lzw=1; // compress
0078unsigned char sizeOfCTD; // depthD-1
0079unsigned char outBufD[260];
0080int bitPtrD;
0081int bitsD;
0082FILE *fpD;
0083int gsize=1; // gif scale
0084
0085/**************** for CRC ********************/
0086unsigned long crc_table[256];
0087int crc_table_computed=0;
0088
0089/************* color table ******************/
0090int std256[256][4]={
0091  0,65535,65535,65535,
0092  1,65535,65535,52428,
0093  2,65535,65535,39321,
0094  3,65535,65535,26214,
0095  4,65535,65535,13107,
0096  5,65535,65535,    0,
0097  6,65535,52428,65535,
0098  7,65535,52428,52428,
0099  8,65535,52428,39321,
0100  9,65535,52428,26214,
0101  10,65535,52428,13107,
0102  11,65535,52428,    0,
0103  12,65535,39321,65535,
0104  13,65535,39321,52428,
0105  14,65535,39321,39321,
0106  15,65535,39321,26214,
0107  16,65535,39321,13107,
0108  17,65535,39321,    0,
0109  18,65535,26214,65535,
0110  19,65535,26214,52428,
0111  20,65535,26214,39321,
0112  21,65535,26214,26214,
0113  22,65535,26214,13107,
0114  23,65535,26214,    0,
0115  24,65535,13107,65535,
0116  25,65535,13107,52428,
0117  26,65535,13107,39321,
0118  27,65535,13107,26214,
0119  28,65535,13107,13107,
0120  29,65535,13107,    0,
0121  30,65535,    0,65535,
0122  31,65535,    0,52428,
0123  32,65535,    0,39321,
0124  33,65535,    0,26214,
0125  34,65535,    0,13107,
0126  35,65535,    0,    0,
0127  36,52428,65535,65535,
0128  37,52428,65535,52428,
0129  38,52428,65535,39321,
0130  39,52428,65535,26214,
0131  40,52428,65535,13107,
0132  41,52428,65535,    0,
0133  42,52428,52428,65535,
0134  43,52428,52428,52428,
0135  44,52428,52428,39321,
0136  45,52428,52428,26214,
0137  46,52428,52428,13107,
0138  47,52428,52428,    0,
0139  48,52428,39321,65535,
0140  49,52428,39321,52428,
0141  50,52428,39321,39321,
0142  51,52428,39321,26214,
0143  52,52428,39321,13107,
0144  53,52428,39321,    0,
0145  54,52428,26214,65535,
0146  55,52428,26214,52428,
0147  56,52428,26214,39321,
0148  57,52428,26214,26214,
0149  58,52428,26214,13107,
0150  59,52428,26214,    0,
0151  60,52428,13107,65535,
0152  61,52428,13107,52428,
0153  62,52428,13107,39321,
0154  63,52428,13107,26214,
0155  64,52428,13107,13107,
0156  65,52428,13107,    0,
0157  66,52428,    0,65535,
0158  67,52428,    0,52428,
0159  68,52428,    0,39321,
0160  69,52428,    0,26214,
0161  70,52428,    0,13107,
0162  71,52428,    0,    0,
0163  72,39321,65535,65535,
0164  73,39321,65535,52428,
0165  74,39321,65535,39321,
0166  75,39321,65535,26214,
0167  76,39321,65535,13107,
0168  77,39321,65535,    0,
0169  78,39321,52428,65535,
0170  79,39321,52428,52428,
0171  80,39321,52428,39321,
0172  81,39321,52428,26214,
0173  82,39321,52428,13107,
0174  83,39321,52428,    0,
0175  84,39321,39321,65535,
0176  85,39321,39321,52428,
0177  86,39321,39321,39321,
0178  87,39321,39321,26214,
0179  88,39321,39321,13107,
0180  89,39321,39321,    0,
0181  90,39321,26214,65535,
0182  91,39321,26214,52428,
0183  92,39321,26214,39321,
0184  93,39321,26214,26214,
0185  94,39321,26214,13107,
0186  95,39321,26214,    0,
0187  96,39321,13107,65535,
0188  97,39321,13107,52428,
0189  98,39321,13107,39321,
0190  99,39321,13107,26214,
0191  100,39321,13107,13107,
0192  101,39321,13107,    0,
0193  102,39321,    0,65535,
0194  103,39321,    0,52428,
0195  104,39321,    0,39321,
0196  105,39321,    0,26214,
0197  106,39321,    0,13107,
0198  107,39321,    0,    0,
0199  108,26214,65535,65535,
0200  109,26214,65535,52428,
0201  110,26214,65535,39321,
0202  111,26214,65535,26214,
0203  112,26214,65535,13107,
0204  113,26214,65535,    0,
0205  114,26214,52428,65535,
0206  115,26214,52428,52428,
0207  116,26214,52428,39321,
0208  117,26214,52428,26214,
0209  118,26214,52428,13107,
0210  119,26214,52428,    0,
0211  120,26214,39321,65535,
0212  121,26214,39321,52428,
0213  122,26214,39321,39321,
0214  123,26214,39321,26214,
0215  124,26214,39321,13107,
0216  125,26214,39321,    0,
0217  126,26214,26214,65535,
0218  127,26214,26214,52428,
0219  128,26214,26214,39321,
0220  129,26214,26214,26214,
0221  130,26214,26214,13107,
0222  131,26214,26214,    0,
0223  132,26214,13107,65535,
0224  133,26214,13107,52428,
0225  134,26214,13107,39321,
0226  135,26214,13107,26214,
0227  136,26214,13107,13107,
0228  137,26214,13107,    0,
0229  138,26214,    0,65535,
0230  139,26214,    0,52428,
0231  140,26214,    0,39321,
0232  141,26214,    0,26214,
0233  142,26214,    0,13107,
0234  143,26214,    0,    0,
0235  144,13107,65535,65535,
0236  145,13107,65535,52428,
0237  146,13107,65535,39321,
0238  147,13107,65535,26214,
0239  148,13107,65535,13107,
0240  149,13107,65535,    0,
0241  150,13107,52428,65535,
0242  151,13107,52428,52428,
0243  152,13107,52428,39321,
0244  153,13107,52428,26214,
0245  154,13107,52428,13107,
0246  155,13107,52428,    0,
0247  156,13107,39321,65535,
0248  157,13107,39321,52428,
0249  158,13107,39321,39321,
0250  159,13107,39321,26214,
0251  160,13107,39321,13107,
0252  161,13107,39321,    0,
0253  162,13107,26214,65535,
0254  163,13107,26214,52428,
0255  164,13107,26214,39321,
0256  165,13107,26214,26214,
0257  166,13107,26214,13107,
0258  167,13107,26214,    0,
0259  168,13107,13107,65535,
0260  169,13107,13107,52428,
0261  170,13107,13107,39321,
0262  171,13107,13107,26214,
0263  172,13107,13107,13107,
0264  173,13107,13107,    0,
0265  174,13107,    0,65535,
0266  175,13107,    0,52428,
0267  176,13107,    0,39321,
0268  177,13107,    0,26214,
0269  178,13107,    0,13107,
0270  179,13107,    0,    0,
0271  180,    0,65535,65535,
0272  181,    0,65535,52428,
0273  182,    0,65535,39321,
0274  183,    0,65535,26214,
0275  184,    0,65535,13107,
0276  185,    0,65535,    0,
0277  186,    0,52428,65535,
0278  187,    0,52428,52428,
0279  188,    0,52428,39321,
0280  189,    0,52428,26214,
0281  190,    0,52428,13107,
0282  191,    0,52428,    0,
0283  192,    0,39321,65535,
0284  193,    0,39321,52428,
0285  194,    0,39321,39321,
0286  195,    0,39321,26214,
0287  196,    0,39321,13107,
0288  197,    0,39321,    0,
0289  198,    0,26214,65535,
0290  199,    0,26214,52428,
0291  200,    0,26214,39321,
0292  201,    0,26214,26214,
0293  202,    0,26214,13107,
0294  203,    0,26214,    0,
0295  204,    0,13107,65535,
0296  205,    0,13107,52428,
0297  206,    0,13107,39321,
0298  207,    0,13107,26214,
0299  208,    0,13107,13107,
0300  209,    0,13107,    0,
0301  210,    0,    0,65535,
0302  211,    0,    0,52428,
0303  212,    0,    0,39321,
0304  213,    0,    0,26214,
0305  214,    0,    0,13107,
0306  215,61166,    0,    0,
0307  216,56797,    0,    0,
0308  217,48059,    0,    0,
0309  218,43690,    0,    0,
0310  219,34952,    0,    0,
0311  220,30583,    0,    0,
0312  221,21845,    0,    0,
0313  222,17476,    0,    0,
0314  223, 8738,    0,    0,
0315  224, 4369,    0,    0,
0316  225,    0,61166,    0,
0317  226,    0,56797,    0,
0318  227,    0,48059,    0,
0319  228,    0,43690,    0,
0320  229,    0,34952,    0,
0321  230,    0,30583,    0,
0322  231,    0,21845,    0,
0323  232,    0,17476,    0,
0324  233,    0, 8738,    0,
0325  234,    0, 4369,    0,
0326  235,    0,    0,61166,
0327  236,    0,    0,56797,
0328  237,    0,    0,48059,
0329  238,    0,    0,43690,
0330  239,    0,    0,34952,
0331  240,    0,    0,30583,
0332  241,    0,    0,21845,
0333  242,    0,    0,17476,
0334  243,    0,    0, 8738,
0335  244,    0,    0, 4369,
0336  245,61166,61166,61166,
0337  246,56797,56797,56797,
0338  247,48059,48059,48059,
0339  248,43690,43690,43690,
0340  249,34952,34952,34952,
0341  250,30583,30583,30583,
0342  251,21845,21845,21845,
0343  252,17476,17476,17476,
0344  253, 8738, 8738, 8738,
0345  254, 4369, 4369, 4369,
0346  255,    0,    0,    0};
0347
0348/****************** for MakeView1 *******************/
0349/**************** basic draw information ***********/
0350/* unsigned char* pD; // bitmap buffer */
0351PixMap* pD1=NULL;
0352/* int depthD; // Mac standard 256 colors */
0353/* int widthD; // picture size */
0354/* int heightD; */
0355/* int coloD; // current color for drawing */
0356unsigned char rD1,gD1,bD1;
0357/* int xD; // current pen position */
0358/* int yD; */
0359/* int cliplD; // clip rect left */
0360/* int cliprD; */
0361/* int cliptD; */
0362/* int clipbD; */
0363PixMap* pD2=NULL;
0364PixMap* pD3=NULL; /* for thumbnail */
0365
0366/**************** for polygon ***************/
0367/* unsigned char* poD; // bitmap buffer */
0368/* int polyWidthD; // number of chars for one line of poD */
0369/* int firstPtxD; // x value of first point. saved for closure */
0370/* int firstPtyD; */
0371/* int vertXD; // left-upper line crossings */
0372/* int horiXD; // upper-left line crossings */
0373/* int polyD; // 1 if polygon mode */
0374/* int pxminD,pxmaxD,pyminD,pymaxD; // bounding rect */
0375
0376/************** saving gif in directory pc ********************/
0377int saveG=0;
0378char saveGfn[30];
0379FILE *gfp;
0380
0381/***************** for GifPaste *************************/
0382unsigned char inBuf[260];
0383int bitPtr;
0384int bitPtrMax; // bit pointer mark for supplying new data
0385int pteByte;   // past-the-end index to inBuf[]
0386int bits;
0387int bitsmin;
0388int TermRead;
0389FILE * infile;         /* source file */
0390
0391int *prec;  // precedence
0392unsigned char *color; // color
0393unsigned char *cbuff; // output color id buffer
0394int nxtCode;
0395int newCode;
0396int oldCode;
0397int clrcode;
0398
0399unsigned char buff[256];
0400
0401/************************** for base64 encode ********************************/
0402int k64=0,l64=0;
0403unsigned char in64[4],out64[5];
0404char b64digits[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
0405
0406int collect(void);
0407int decode(int i,int code);
0408
0409int MakeView(int width,int height)
0410{
0411  int i,j;
0412  widthD=width;
0413  heightD=height;
0414  pD=(unsigned char *)malloc((widthD+1)*heightD*sizeof(char));
0415  j=widthD*heightD;
0416  for(i=0;i<j;i++) pD[i]=0;
0417  depthD=8;
0418  if(widthD%8==0) polyWidthD=widthD/8; // width for buffer
0419  else polyWidthD=width/8+1;
0420  poD=(unsigned char *)malloc(polyWidthD*heightD*sizeof(char));
0421  cliplD=0; // clip rect left
0422  cliprD=widthD;
0423  cliptD=0;
0424  clipbD=heightD;
0425  polyD=0; // not polygon mode initially
0426  widMin=0;
0427  widMax=widthD;
0428  heiMin=0;
0429  heiMax=heightD;
0430}
0431
0432int MakeView1(int type,int width,int height)
0433{
0434  int i,j;
0435  widthD=width;
0436  heightD=height;
0437  /* pD=(unsigned char *)malloc((widthD+1)*heightD*sizeof(char)); */
0438  pD1=pcreate(type,widthD,heightD);
0439  /* j=widthD*heightD; */
0440  /* for(i=0;i<j;i++) pD[i]=0; */
0441  /* depthD=8; */
0442  if(widthD%8==0) polyWidthD=widthD/8; // width for buffer
0443  else polyWidthD=width/8+1;
0444  poD=(unsigned char *)malloc(polyWidthD*heightD*sizeof(char));
0445  cliplD=0; // clip rect left
0446  cliprD=widthD;
0447  cliptD=0;
0448  clipbD=heightD;
0449  polyD=0; // not polygon mode initially
0450  widMin=0;
0451  widMax=widthD;
0452  heiMin=0;
0453  heiMax=heightD;
0454}
0455
0456int SetColor(int r1,int g1,int b1)
0457{
0458  int i;
0459  int r,g,b;
0460  
0461  r=r1*(0xffff/100);
0462  g=g1*(0xffff/100);
0463  b=b1*(0xffff/100);
0464  return SetColor1(r,g,b);
0465}
0466
0467int SetColor1(int r,int g,int b)
0468{
0469  int i;
0470  if(pD1==NULL){
0471    if(r==0&&g==0&&b==0){
0472      coloD=255;
0473      return;
0474    }
0475    if(r==0xffff&&g==0xffff&&b==0xffff){
0476      coloD=0;
0477      return;
0478    }
0479    if(r==0&&g==0){
0480      i=(b+2185)/4369;
0481      if(i%3!=0){
0482        coloD=245-(i-i/3);
0483        return;
0484      }
0485    }
0486    if(g==0&&b==0){
0487      i=(r+2185)/4369;
0488      if(i%3!=0){
0489        coloD=225-(i-i/3);
0490        return;
0491      }
0492    }
0493    if(b==0&&r==0){
0494      i=(g+2185)/4369;
0495      if(i%3!=0){
0496        coloD=235-(i-i/3);
0497        return;
0498      }
0499    }
0500    if(b==g&&r==g){ // gray scale
0501      i=(g+2185)/4369;
0502      if(i!=0&&i%3!=0){
0503        coloD=255-(i-i/3);
0504        return;
0505      }
0506    }
0507    coloD=215-((r+6554)/13107)*36-((g+6554)/13107)*6-(b+6554)/13107;
0508    if(coloD==215) coloD=255;
0509  }
0510  else{
0511    switch(pD1->type){
0512    case 0: /* black and white */
0513      if(r>0) coloD=1;
0514      else coloD=0;
0515      break;
0516    case 1: /* 4-bit gray scale */
0517      coloD=r*16/0xffff;
0518      if(coloD==16) coloD=15;
0519      break;
0520    case 4: /* 24-bit colors */
0521      rD1=r>>8;
0522      gD1=g>>8;
0523      bD1=b>>8;
0524      break;
0525    case 6: /* black, white, red, blue */
0526      if(g>0) coloD=1;
0527      else if(r>0) coloD=2;
0528      else if(b>0) coloD=3;
0529      else coloD=0;
0530      break;
0531    case 7: /* 14 colors */  
0532      coloD=0;
0533      if(r+g+b>0x17ffd) coloD|=8;
0534      if(-r+g+b>0x7fff) coloD|=4;
0535      if(r-g+b>0x7fff) coloD|=2;
0536      if(r+g-b>0x7fff) coloD|=1;
0537      break;
0538    case 9: /* 256 standard */
0539      if(r==0&&g==0&&b==0){
0540        coloD=255;
0541        return;
0542      }
0543      if(r==0xffff&&g==0xffff&&b==0xffff){
0544        coloD=0;
0545        return;
0546      }
0547      if(r==0&&g==0){
0548        i=(b+2185)/4369;
0549        if(i%3!=0){
0550          coloD=245-(i-i/3);
0551          return;
0552        }
0553      }
0554      if(g==0&&b==0){
0555        i=(r+2185)/4369;
0556        if(i%3!=0){
0557          coloD=225-(i-i/3);
0558          return;
0559        }
0560      }
0561      if(b==0&&r==0){
0562        i=(g+2185)/4369;
0563        if(i%3!=0){
0564          coloD=235-(i-i/3);
0565          return;
0566        }
0567      }
0568      if(b==g&&r==g){ // gray scale
0569        i=(g+2185)/4369;
0570        if(i!=0&&i%3!=0){
0571          coloD=255-(i-i/3);
0572          return;
0573        }
0574      }
0575      coloD=215-((r+6554)/13107)*36-((g+6554)/13107)*6-(b+6554)/13107;
0576      if(coloD==215) coloD=255;
0577      break;
0578    }
0579  } 
0580}
0581
0582int SetColorId(int id)
0583{
0584  if(pD1==NULL) return 1;
0585  coloD=id;
0586}
0587
0588int PalettePeek(int id,int *r,int *g,int *b)
0589{
0590  unsigned char *cp;
0591  if(pD1==NULL) return 1;
0592  cp=(unsigned char *)&pD1->data[0];
0593  *r=cp[id*3];
0594  *g=cp[id*3+1];
0595  *b=cp[id*3+2];
0596  return 0;
0597}
0598
0599int PalettePoke(int id,int r,int g,int b)
0600{
0601  unsigned char *cp;
0602  if(pD1==NULL) return 1;
0603  cp=(unsigned char *)&pD1->data[0];
0604  cp[id*3]=r&0xff;
0605  cp[id*3+1]=g&0xff;
0606  cp[id*3+2]=b&0xff;
0607  return 0;
0608}
0609
0610int MoveTo(int x,int y)
0611{
0612  if(polyD){
0613    firstPtxD=x;
0614    firstPtyD=y;
0615    if(x<pxminD) pxminD=x;
0616    if(x>pxmaxD) pxmaxD=x;
0617    if(y<pyminD) pyminD=y;
0618    if(y>pymaxD) pymaxD=y;
0619  }
0620  xD=x;
0621  yD=y;
0622}
0623
0624int LineTo(int x1,int y1)
0625{
0626  int a,dx,dy,b,two_a,two_b,xcrit,eps;
0627  unsigned char i;
0628  if(polyD){
0629    if(x1<pxminD) pxminD=x1;
0630    if(x1>pxmaxD) pxmaxD=x1;
0631    if(y1<pyminD) pyminD=y1;
0632    if(y1>pymaxD) pymaxD=y1;
0633    if(xD*x1<0){
0634      if((xD*y1-yD*x1)/(xD-x1)<0) vertXD++;
0635    }
0636    if(yD*y1<0){
0637      if((yD*x1-xD*y1)/(yD-y1)<0) horiXD++;
0638    }
0639  }
0640  dx=1;
0641  a=x1-xD;
0642  if(a<0){
0643    dx=-1;
0644    a=-a;
0645  }
0646
0647  dy=1;
0648  b=y1-yD;
0649  if(b<0){
0650    dy=-1;
0651    b=-b;
0652  }
0653  two_a = 2*a;
0654  two_b = 2*b;
0655  xcrit = -b+two_a;
0656  eps=0;
0657
0658  for(;;){
0659    if(cliplD<=xD && xD<cliprD && cliptD<=yD && yD<clipbD){
0660      if(polyD){
0661        i=1<<(xD%8);
0662        poD[yD*polyWidthD+xD/8]|=i;
0663      }
0664      else{
0665        if(pD1){
0666          if(pD1->type==4) putpix(pD1,xD,yD,rD1,gD1,bD1);
0667          else putpixid(pD1,xD,yD,coloD);
0668        }
0669        else *(pD+yD*widthD+xD)=coloD;
0670      }
0671    }
0672    if(xD==x1&&yD==y1) break;
0673    if(eps<=xcrit) xD += dx, eps+=two_b;
0674    if(eps>=a || a<=b) yD += dy, eps-=two_a;
0675  }
0676}
0677
0678void drawGrid()
0679{
0680  int i,j,k,l;
0681  SetColor(100,70,60);
0682  for(i=0;i<heightD;i+=10){
0683    MoveTo(0,i);
0684    LineTo(widthD,i);
0685  }
0686  for(i=0;i<widthD;i+=10){
0687    MoveTo(i,0);
0688    LineTo(i,heightD);
0689  }
0690  SetColor(75,40,20);
0691  for(i=0;i<heightD;i+=50){
0692    MoveTo(0,i);
0693    LineTo(widthD,i);
0694  }
0695  for(i=0;i<widthD;i+=50){
0696    MoveTo(i,0);
0697    LineTo(i,heightD);
0698  }
0699  SetColor(40,20,10);
0700  for(i=0;i<heightD;i+=100){
0701    MoveTo(0,i);
0702    LineTo(widthD,i);
0703  }
0704  for(i=0;i<widthD;i+=100){
0705    MoveTo(i,0);
0706    LineTo(i,heightD);
0707  }
0708  SetColor(80,80,80);
0709  for(i=0;i<heightD;i+=100){
0710    j=i/1000;
0711    k=(i/100)%10;
0712    for(l=0;l<widthD-100;l+=100){
0713      MoveTo(l+50-j*5,i);
0714      LineTo(l+50-j*5-5,i);
0715      MoveTo(l+100-k*5,i);
0716      LineTo(l+100-k*5-5,i);
0717    }
0718  }
0719  for(i=0;i<widthD;i+=100){
0720    j=i/1000;
0721    k=(i/100)%10;
0722    for(l=0;l<heightD-100;l+=100){
0723      MoveTo(i,l+50+j*5);
0724      LineTo(i,l+50+j*5+5);
0725      MoveTo(i,l+k*5);
0726      LineTo(i,l+k*5+5);
0727    }
0728  }
0729}
0730
0731int OpenPoly()
0732{
0733  int i,j;
0734  for(j=0;j<heightD;j++)
0735    for(i=0;i<polyWidthD;i++) poD[j*polyWidthD+i]=0;
0736  polyD=1; // polygon mode on
0737  vertXD=0; // left-upper line crossings
0738  horiXD=0;
0739  pxminD=10000;
0740  pxmaxD=-10000;
0741  pyminD=10000;
0742  pymaxD=-10000;
0743}
0744
0745int SeedFill(int i)
0746{
0747  seedD=i;
0748}
0749
0750int ClosePoly()
0751{
0752  /* [item][island][line]
0753     item 0 first column
0754     item 1 last column
0755     item 2 first upper continuous island (if -1 no upper island)
0756     item 3 second upper continuous island
0757     item 4 first lower continuous island (if -1 no lower island)
0758     item 5 second lower continuous island
0759     item 6 degenerative island (if 1)
0760     item 7 left corner (if 1)
0761     item 8 right corner (if 1)
0762  */
0763  int isl[3]; // number of islands
0764  int transitD[9][10][3]; // first black points and last black points
0765  // for three lines
0766  int cornerBlack;
0767  int i,j,k,l,n,i1,i2,i3,i4,i5,i6,i7,i8,i9;
0768  int topin; // top is inside
0769  int leftin; // left is inside
0770  unsigned char m;
0771  /* seed-fill mode */
0772  int seedx,seedy;
0773  Segment stack[MAX],*sp=stack;
0774  int x,y,x1,x2,dy;
0775
0776  char s[100];
0777
0778  if(seedD==1){
0779    seedx=-1;
0780    seedy=-1;
0781  }
0782  LineTo(firstPtxD,firstPtyD); // close polygon
0783  polyD=0; // polygon mode off
0784  if(pxminD>=widthD) return; // out of view
0785  if(pxmaxD<0) return;
0786  if(pyminD>=heightD) return;
0787  if(pymaxD<0) return;
0788
0789  pxmaxD++; // past-the-boundary value
0790  pymaxD++;
0791
0792  if(pxminD<0){
0793    pxminD=0; // crossing rect
0794    leftin=0;
0795  }
0796  else leftin=1;
0797  if(pxmaxD>widthD) pxmaxD=widthD;
0798  if(pyminD<0){
0799    pyminD=0;
0800    topin=0;
0801  }
0802  else topin=1; // top is in the view
0803  if(pymaxD>heightD) pymaxD=heightD;
0804
0805  if(pxminD==(pxmaxD-1)) return;
0806  if(pyminD==(pymaxD-1)) return;
0807  
0808  cornerBlack=0; // upper left corner is white
0809  if(pxminD==0&&pyminD==0){
0810    if(vertXD%2==1) cornerBlack=1;
0811  }
0812  i9=cornerBlack; /* starting color condition */
0813  for(j=pyminD;j<pymaxD;j++){
0814    for(k=0;k<10;k++)
0815      for(n=0;n<9;n++){
0816        transitD[n][k][0]=transitD[n][k][1];
0817        transitD[n][k][1]=transitD[n][k][2];
0818        transitD[n][k][2]=-1;
0819      }
0820    isl[0]=isl[1];
0821    isl[1]=isl[2];
0822    k=0; // point white
0823    isl[2]=0;
0824    for(i=pxminD;i<pxmaxD;i++){
0825      m=poD[j*polyWidthD+i/8];
0826      if(m&(1<<(i%8))){ // black
0827        if(k==0){
0828          transitD[0][isl[2]][2]=i; // first black
0829          k=1;
0830        }
0831        if(i==pxminD) transitD[7][isl[2]][2]=1;
0832        if(i==pxmaxD-1) transitD[8][isl[2]][2]=1;
0833      }
0834      else{ // white
0835        if(k==1){
0836          transitD[1][isl[2]][2]=i-1; // last black
0837          k=0;
0838          if(isl[2]<9) isl[2]++;
0839        }
0840      }
0841    } /* for(i=pxminD;i<pxmaxD;i++) */
0842    if(k==1){
0843      transitD[1][isl[2]][2]=i-1; // last point is black
0844      transitD[8][isl[2]][2]=1;
0845      if(isl[2]<9) isl[2]++;
0846    }
0847    if(j==pyminD&&isl[2]==0){
0848      pyminD++;
0849      continue;
0850    }
0851    if(j>pyminD){ // if line 1 and above , process line 0
0852      for(k=0;k<isl[1];k++){
0853        i1=transitD[0][k][1];
0854        i2=transitD[1][k][1];
0855        i3=0;
0856        for(i4=0;i4<isl[2];i4++){
0857          i5=transitD[0][i4][2];
0858          i6=transitD[1][i4][2];
0859          if(i6>=(i1-1)&&i5<=(i2+1)){
0860            if(i3<2) transitD[4+i3][k][1]=i4; // lower
0861            i3++;
0862          }
0863        }
0864      } /* for(k=0;k<isl[1];k++){ */
0865      for(k=0;k<isl[2];k++){
0866        i1=transitD[0][k][2];
0867        i2=transitD[1][k][2];
0868        i3=0;
0869        for(i4=0;i4<isl[1];i4++){
0870          i5=transitD[0][i4][1];
0871          i6=transitD[1][i4][1];
0872          if(i6>=(i1-1)&&i5<=(i2+1)){
0873            if(i3<2) transitD[2+i3][k][2]=i4; // upper
0874            i3++;
0875          }
0876        }
0877      } /* for(k=0;k<isl[2];k++){ */
0878      if(j==pyminD+1){ // for the second line
0879        if(topin){
0880          for(k=0;k<isl[1];k++){
0881            if(transitD[5][k][1]!=-1) transitD[6][k][1]=1; // two lowers - degenerative
0882            else if(transitD[8][k][1]!=1&&transitD[7][k][1]!=1){ // one lower and not right or left corner
0883              transitD[6][k][1]=1; // one lower - consecutive degenerative
0884              if(transitD[4][k][1]!=-1) transitD[6][ transitD[4][k][1] ][2]=1; // make the lower degenerative
0885            }
0886          }
0887          for(k=0;k<isl[2];k++){
0888            if(transitD[2][k][2]==-1){
0889              if(transitD[8][k][2]!=1&&transitD[7][k][2]!=1) transitD[6][k][2]=1; // no uppers and not right edge
0890            }
0891          }
0892        } /* if(topin){ */
0893      } /* if(j==pyminD+1){ */
0894    } /* if(j>pyminD) */
0895    if(j>pyminD+1){ // re-evaluate 3-line data and fill first line
0896      for(k=0;k<isl[2];k++){
0897        if(transitD[2][k][2]==-1){
0898          if(transitD[8][k][2]!=1&&transitD[7][k][2]!=1) transitD[6][k][2]=1; // no uppers and not edge
0899        }
0900        else if(transitD[3][k][2]==-1&&transitD[6][ transitD[2][k][2] ][1]==1){ // one upper and it's degenerative
0901          if(transitD[5][ transitD[2][k][2] ][1]==-1) transitD[6][k][2]=1; // the upper has one lower
0902        }
0903      }
0904      for(k=0;k<isl[2];k++){
0905        if(transitD[3][k][2]!=-1)  transitD[6][k][2]=1; // second-upper exists. join
0906      }
0907      for(k=0;k<isl[1];k++){
0908        if(transitD[5][k][1]!=-1){ // second-lower exists. cancel lowers' degene
0909          transitD[6][ transitD[4][k][1] ][2]=-1;
0910          transitD[6][ transitD[5][k][1] ][2]=-1;
0911        }
0912      }
0913      i8=i9; // starting color
0914      if(leftin==0){
0915        if(transitD[7][0][1]==1&&transitD[7][0][0]==-1){
0916          if(transitD[2][0][1]==-1&&transitD[4][0][1]!=-1){
0917            if(i9==1) i9=0;
0918            else i9=1;
0919          }
0920        }
0921        if(transitD[7][0][0]==1&&transitD[7][0][1]==-1){
0922          if(transitD[2][0][0]!=-1&&transitD[4][0][0]==-1){
0923            if(i9==1) i9=0;
0924            else i9=1;
0925          }
0926        }
0927      }
0928      if(j==pyminD+2&&transitD[0][0][0]==0){
0929        if( i9==1) i9=0;
0930        else i9=1;
0931        i8=i9;
0932      }
0933      i7=pxminD;
0934      for(k=0;k<isl[0];k++){
0935        i1=transitD[0][k][0];
0936        if(i8){ // if black, paint from i7 to i1
0937          if(seedD==1&&i7<i1){
0938            for(l=i7;l<i1;l++){
0939              if(!(poD[(j-2)*polyWidthD+l/8]&(1<<l%8))){
0940               seedx=l;
0941               seedy=j-2;
0942               break;
0943              }
0944            }
0945            if(l<i1) break;
0946          }
0947          for(l=i7;l<i1;l++)
0948            poD[(j-2)*polyWidthD+l/8]|=(1<<l%8);
0949        }
0950        if(transitD[6][k][0]!=1){
0951          if(i8==1) i8=0;
0952          else i8=1;
0953        }
0954        i7=transitD[1][k][0]+1;
0955      } /* for(k=0;k<isl[0];k++) */
0956      if(seedD==1&&seedx!=-1) break;
0957      if(i8==1&&i7<pxmaxD){ // paint to the end of line
0958        if(seedD==1){
0959          for(l=i7;l<pxmaxD;l++){
0960            if(!(poD[(j-2)*polyWidthD+l/8]&(1<<l%8))){
0961              seedx=l;
0962              seedy=j-2;
0963              break;
0964            }
0965          }
0966          if(l<pxmaxD) break;
0967        }
0968        for(l=i7;l<pxmaxD;l++)
0969          poD[(j-2)*polyWidthD+l/8]|=(1<<l%8);
0970      }
0971    } /* if(j>pymind+1) */      
0972  } /* for(j=pyminD;j<pymaxD,j++) */
0973  /* now do for last two lines */
0974  if(seedD!=1)
0975    for(j=1;j<3;j++){
0976      i8=i9;
0977      /*   if(j==1&&leftin==0){
0978           if(transitD[7][0][2]==1&&transitD[7][0][1]==-1){
0979           if(i9==1) i9=0;
0980           else i9=1;
0981           }
0982           }*/
0983      i7=pxminD;
0984      for(k=0;k<isl[j];k++){
0985        i1=transitD[0][k][j];
0986        if(i8){ // if black, paint from i7 to i1
0987          for(l=i7;l<i1;l++)
0988            poD[(pymaxD-3+j)*polyWidthD+l/8]|=(1<<l%8);
0989        }
0990        if(transitD[6][k][j]!=1){
0991          if(i8==1) i8=0;
0992          else i8=1;
0993        }
0994        i7=transitD[1][k][j]+1;
0995      }
0996      if(i8==1&&i7<pxmaxD){ // paint to the end of line
0997        for(l=i7;l<pxmaxD;l++)
0998          poD[(pymaxD-3+j)*polyWidthD+l/8]|=(1<<l%8);
0999      }
1000    }
1001  /* seed fill */
1002  /*sprintf(s,"seedx=%i seedy=%i\n",seedx,seedy);
1003    outbyte(strlen(s),s);
1004    flush();
1005    return;*/
1006  if(seedD==1&&seedx!=-1){
1007    x=seedx;
1008    y=seedy;
1009    PUSH(y,x,x,1);
1010    PUSH(y+1,x,x,-1);
1011    while(sp>stack){
1012      POP(y,x1,x2,dy);
1013      for(x=x1;x>=0&&!(poD[y*polyWidthD+x/8]&(1<<x%8));x--) poD[y*polyWidthD+x/8]|=(1<<x%8);
1014      if(x>=x1) goto skip;
1015      l=x+1;
1016      if(l<x1) PUSH(y,l,x1-1,-dy);
1017      x=x1+1;
1018      do{
1019        for(;x<widthD&&!(poD[y*polyWidthD+x/8]&(1<<x%8));x++) poD[y*polyWidthD+x/8]|=(1<<x%8);
1020        PUSH(y,l,x-1,dy);
1021        if(x>x2+1) PUSH(y,x2+1,x-1,-dy);
1022      skip: for(x++;x<=x2&&(poD[y*polyWidthD+x/8]&(1<<x%8));x++);
1023        l=x;
1024      }while(x<=x2);
1025    }
1026  }
1027  /* now poD has been painted, next we will paint pD in coloD */
1028  for(j=pyminD;j<pymaxD;j++){
1029    for(i=pxminD;i<pxmaxD;i++){
1030      m=poD[j*polyWidthD+i/8];
1031      if(m&(1<<(i%8)))
1032        if(pD1){
1033          if(pD1->type==4) putpix(pD1,i,j,rD1,gD1,bD1);
1034          else putpixid(pD1,i,j,coloD);
1035        }
1036        else *(pD+j*widthD+i)=coloD;
1037    }
1038  }
1039}
1040
1041int FontInfo(int font,int direc,int mode)
1042{
1043  fontD=font;
1044  switch(font){
1045  case 11: // 6x11
1046    pfD=fontdata_6x11;
1047    ascentD=8;
1048    descentD=3;
1049    fontWidthD=6;
1050    fontHeightD=11;
1051    widthBytesD=1;
1052    fontBytesD=11;
1053    break;
1054  case 16: // 8x16
1055    pfD=fontdata_8x16;
1056    ascentD=11;
1057    descentD=5;
1058    fontWidthD=8;
1059    fontHeightD=16;
1060    widthBytesD=1;
1061    fontBytesD=16;
1062    break;
1063  case 22: // 12x22
1064    pfD=fontdata_12x22;
1065    ascentD=16;
1066    descentD=6;
1067    fontWidthD=12;
1068    fontHeightD=22;
1069    widthBytesD=2;
1070    fontBytesD=44;
1071    break;
1072  }
1073  direcD=direc;
1074  modeD=mode;
1075}
1076
1077int DrawString(char *c)
1078{
1079  long int dots[1056]; // up to and including double size of 12x22
1080  int h,i,j,k,l,m,n,k0,x,y;
1081  unsigned char test,mask;
1082
1083  if(modeD==0);
1084  else{
1085    i=strlen(c);
1086    i=i*fontWidthD;
1087    if(modeD==2) i/=2; /* center */
1088    if(direcD==0) xD-=i;
1089    else yD+=i;
1090  }
1091  for(h=0;c[h]!='\0';h++){
1092    k0=fontBytesD*(int)c[h];
1093    n=0;
1094    for(i=0;i<fontHeightD;i++){
1095      k=k0+i*widthBytesD;
1096      m=0;
1097      for(j=0;j<widthBytesD;j++){
1098        test=pfD[k+j];
1099        mask=0x80;
1100        for(l=0;l<8;l++){
1101          if(test&mask){
1102            if(direcD==0){ // horizontal
1103              y=yD-ascentD+i;
1104              x=xD+j*8+l;
1105            }
1106            else{ // vertical
1107              x=xD-ascentD+i;
1108              y=yD-j*8-l;
1109            }
1110            if(x>=0&&x<widthD&&y>=0&&y<heightD)
1111              dots[n++]=y*widthD+x;
1112          }
1113          mask>>=1;
1114          m++;
1115          if(m==fontWidthD) break;
1116        }
1117      }
1118    } /* for(i=0;i<fontHeightD;i++) */
1119    for(j=0;j<n;j++){
1120      if(pD1){
1121        if(pD1->type==4) putpix(pD1,dots[j]%widthD,dots[j]/widthD,rD1,gD1,bD1);
1122        else putpixid(pD1,dots[j]%widthD,dots[j]/widthD,coloD);
1123      }
1124      else *(pD+dots[j])=coloD;
1125    }
1126    if(direcD==0) xD+=fontWidthD;
1127    else yD-=fontWidthD;
1128  } /* for(h=0;c[h]!='\0';h++) */
1129}
1130
1131int DrawNum(int i)
1132{
1133  char c[15];
1134  sprintf(c,"%i",i);
1135  DrawString(c);
1136}
1137
1138int DrawFNum(char *f,double a)
1139{
1140  char c[30];
1141  sprintf(c,f,a);
1142  DrawString(c);
1143} 
1144
1145int MakeGraph(int left,int top,int right,int bottom)
1146{
1147  lgD=left;
1148  tgD=top;
1149  rgD=right;
1150  bgD=bottom;
1151  htD=0;
1152  hlD=0;
1153  vlD=0;
1154}
1155
1156int HorizTime()
1157{
1158  htD=1;
1159}
1160
1161int HorizLog()
1162{
1163  hlD=1;
1164}
1165
1166int VertLog()
1167{
1168  vlD=1;
1169}
1170
1171int format(int col,double num,char* fig)
1172{
1173  int i,j,colst,inte1,ncha;
1174  double a,frac;
1175  double inte;
1176  char c[10]={'0','1','2','3','4','5','6','7','8','9'};
1177
1178  ncha=0;
1179  i=0;
1180  if(num<0.){
1181    i++;
1182    fig[ncha++]='-';
1183    num=fabs(num);
1184  }
1185
1186  if(num!=0.){
1187    a=log10(num);
1188    frac=modf(a,&inte);
1189    colst=inte+0.1;
1190    if(colst<0) colst=0;
1191  }
1192  else colst=0;
1193        
1194  num+=pow(10,colst-6);
1195        
1196  frac=num/pow(10,colst);
1197  if(frac<1.&&frac>0.9999) frac=1.;
1198  for(j=colst;j>=0;j--){
1199    if(frac<1.&&frac>0.9999) frac=1.;
1200    frac=modf(frac,&inte)*10.;
1201    inte1=inte;
1202    i++;
1203    fig[ncha++]=c[inte1];
1204  }
1205
1206  if(col!=0){
1207    i++;
1208    fig[ncha++]='.';
1209    for(j=col;j>0;j--){
1210      if(frac<1.&&frac>0.9999) frac=1.;
1211      frac=modf(frac,&inte)*10.;
1212      inte1=inte;
1213      i++;
1214      fig[ncha++]=c[inte1];
1215    }
1216  }
1217  fig[ncha]='\0';
1218  return i;
1219}
1220
1221
1222int HorizScale(char *c,double left,double right)
1223{
1224  int i,j,ix,colx;
1225  double stepc,stepf,delta,intef,frac,num;
1226  char ar[12];
1227  double mdy,hms,scl;
1228  char *month[]={"Jan","Feb","Mar","Apr","May","Jun",
1229                "Jul","Aug","Sep","Oct","Nov","Dec"};
1230
1231  ldgD=left;
1232  rdgD=right;
1233  delta=right-left;
1234  MoveTo(lgD,bgD);
1235  LineTo(rgD,bgD);
1236  if(htD==0){
1237    frac=modf(log10(delta),&intef);
1238    stepc=pow(10.,intef-1);
1239    stepf=stepc;
1240    if(frac<0.2) stepf*=0.5;
1241    else if(frac<0.8) stepc*=5.;
1242    else{
1243      stepc*=10.;
1244      stepf*=5.;
1245    }
1246    frac=modf(log10(stepc),&intef);
1247    // if(log10(stepc)<0.) colx=-intef+1.;
1248    if(log10(stepc)<0.) colx=-log10(stepc)+0.8;
1249    else colx=0;
1250    frac=modf(left/stepc,&intef);
1251    frac=intef;
1252    if(hlD){
1253      stepc=1.;
1254      colx=0;
1255    }
1256    while(1){
1257      num=frac*stepc;                        // x value for grid
1258      if(num>rdgD) break;
1259      ix=(rgD-lgD)*((num-ldgD)/(rdgD-ldgD))+lgD;
1260      i=format(colx,num,ar);
1261      MoveTo(ix,tgD);
1262      LineTo(ix,bgD+2);
1263      FontInfo(11,0,0);
1264      for(i=0;ar[i]!='\0';i++);
1265      if(hlD){
1266        MoveTo(ix-i*3+4,bgD+12);
1267        DrawString(ar);
1268        MoveTo(ix-i*3-6,bgD+20);
1269        DrawString("10");
1270      }
1271      else{
1272        MoveTo(ix-i*3,bgD+12);
1273        DrawString(ar);
1274      }
1275      frac++;
1276    }
1277  }
1278  else{ /* horiz is time */
1279    mdy=mdyday(left);
1280    hms=hmsday(left);
1281    scl=(rgD-lgD)/delta;  /* dots per day */
1282    if(delta>700.){ /* yr */   
1283      frac=fmod(mdy*1000000.,10000.);
1284      while(1){
1285        num=refday(1.01+frac/1000000.,0.);     // x value for grid
1286        if(num>rdgD) break;
1287        ix=scl*(num-ldgD)+lgD;
1288        i=format(0,frac,ar);
1289        MoveTo(ix,tgD);
1290        LineTo(ix,bgD+2);
1291        if(num+182.>rdgD) break;
1292        FontInfo(11,0,2); /* center */
1293        ix=scl*(num+182.-ldgD)+lgD;
1294        MoveTo(ix,bgD+12);
1295        if(scl>0.07) DrawString(ar);
1296        else DrawString(&ar[2]);
1297        frac++; /* add a year */
1298      }
1299    }
1300    else if(delta>70.){ /* mo */
1301      stepc=fmod(mdy*1000000.,10000.); 
1302      stepf=floor(mdy);
1303      while(1){
1304        num=refday(stepf+0.01+stepc/1000000.,0.);     // x value for grid
1305        if(num>rdgD) break;
1306        if(num>ldgD){
1307          ix=scl*(num-ldgD)+lgD;
1308          MoveTo(ix,tgD);
1309          LineTo(ix,bgD+2);
1310        }
1311        if(num+15.>rdgD) break;
1312        FontInfo(11,0,2); /* center */
1313        ix=scl*(num+15.-ldgD)+lgD;
1314        MoveTo(ix,bgD+12);
1315        i=stepf;
1316        DrawString(month[i-1]);
1317        stepf++;
1318        if(stepf>12.1){
1319          stepf=1.;
1320          stepc++;
1321        }
1322      }
1323    }
1324    else if(delta>2.){ /* day */
1325      num=refday(mdy,0.);
1326      while(1){
1327        if(num>rdgD) break;
1328        stepf=mdyday(num);
1329        stepc=floor(stepf*100.);
1330        stepf=fmod(stepc,100.);
1331        i=1;
1332        if(scl<12.){
1333          if(fmod(num+0.001,7.)>1.) i=0;
1334        }
1335        if(num>ldgD){
1336          ix=scl*(num-ldgD)+lgD;
1337          MoveTo(ix,tgD);
1338          LineTo(ix,bgD+2*i);
1339        }
1340        if(i==1){
1341          if(num+0.5>rdgD) break;
1342          FontInfo(11,0,2); /* center */
1343          ix=scl*(num+0.5-ldgD)+lgD;
1344          MoveTo(ix,bgD+12);
1345          format(0,stepf,ar);
1346          DrawString(ar);
1347        }
1348        num++;
1349      }
1350    }
1351    else{ /* hour */
1352      stepc=floor(hms);
1353      num=refday(mdy,stepc);
1354      while(1){
1355        if(num>rdgD) break;
1356        if(num>ldgD){
1357          ix=scl*(num-ldgD)+lgD;
1358          MoveTo(ix,tgD);
1359          LineTo(ix,bgD+2);
1360        }
1361        if(num>rdgD) break;
1362        FontInfo(11,0,2); /* center */
1363        ix=scl*(num-ldgD)+lgD;
1364        MoveTo(ix,bgD+12);
1365        i=format(0,stepc,ar);
1366        DrawString(ar);
1367        stepc++;
1368        if(stepc>23.5) stepc=0;
1369        num+=0.041666666;
1370      }
1371    }
1372  }
1373  for(i=0;c[i]!='\0';i++);
1374  if(hlD) MoveTo((lgD+rgD-i*8)/2,bgD+33);
1375  else MoveTo((lgD+rgD-i*8)/2,bgD+22);
1376  FontInfo(16,0,0);
1377  DrawString(c);
1378}
1379
1380int VertScale(char *c,double bottom,double top)
1381{
1382  int i,j,iy,coly;
1383  double stepc,stepf,delta,intef,frac,num;
1384  char ar[12];
1385
1386  bdgD=bottom;
1387  tdgD=top;
1388  delta=top-bottom;
1389  frac=modf(log10(delta),&intef);
1390  stepc=pow(10.,intef-1);
1391  stepf=stepc;
1392  if(frac<0.2) stepf*=0.5;
1393  else if(frac<0.8) stepc*=5.;
1394  else{
1395    stepc*=10.;
1396    stepf*=5.;
1397  }
1398  MoveTo(lgD,tgD);
1399  LineTo(lgD,bgD);
1400
1401  frac=modf(log10(stepc),&intef);
1402  // if(log10(stepc)<0.) coly=-intef+1.;
1403  if(log10(stepc)<0.) coly=-log10(stepc)+0.8;
1404  else coly=0;
1405  frac=modf(bottom/stepc,&intef);
1406  frac=intef;
1407  if(vlD){
1408    stepc=1.;
1409    coly=0;
1410  }
1411  j=0;
1412  while(1){
1413    num=frac*stepc;                        // y value for grid
1414    if(num>tdgD) break;
1415    iy=(tgD-bgD)*((num-bdgD)/(tdgD-bdgD))+bgD;
1416    i=format(coly,num,ar);
1417    if(i>j) j=i;
1418    MoveTo(lgD-2,iy);
1419    LineTo(rgD,iy);
1420    FontInfo(11,0,0);
1421    for(i=0;ar[i]!='\0';i++);
1422    if(vlD){
1423      MoveTo(lgD-i*6-3,iy-1);
1424      DrawString(ar);
1425      MoveTo(lgD-i*6-12,iy+6);
1426      DrawString("10");
1427    }
1428    else{
1429      MoveTo(lgD-i*6-3,iy+3);
1430      DrawString(ar);
1431    }
1432    frac++;
1433  }
1434  for(i=0;c[i]!='\0';i++);
1435  if(vlD) MoveTo(lgD-j*6-16,(bgD+tgD+i*8)/2);
1436  else MoveTo(lgD-j*6-8,(bgD+tgD+i*8)/2);
1437  FontInfo(16,1,0);
1438  DrawString(c);
1439}
1440
1441int MoveToG(double x,double y)
1442{
1443  int savel,saver,savet,saveb;
1444  int ix,iy;
1445 
1446  savel=cliplD;
1447  saver=cliprD;
1448  savet=cliptD;
1449  saveb=clipbD;
1450  cliplD=lgD;
1451  cliprD=rgD;
1452  cliptD=tgD;
1453  clipbD=bgD;
1454
1455  ix=(rgD-lgD)*((x-ldgD)/(rdgD-ldgD))+lgD;
1456  iy=(tgD-bgD)*((y-bdgD)/(tdgD-bdgD))+bgD;
1457  MoveTo(ix,iy);
1458
1459  cliplD=savel;
1460  cliprD=saver;
1461  cliptD=savet;
1462  clipbD=saveb;
1463}
1464
1465int LineToG(double x,double y)
1466{
1467  int savel,saver,savet,saveb;
1468  int ix,iy;
1469 
1470  savel=cliplD;
1471  saver=cliprD;
1472  savet=cliptD;
1473  saveb=clipbD;
1474  cliplD=lgD;
1475  cliprD=rgD;
1476  cliptD=tgD;
1477  clipbD=bgD;
1478
1479 
1480  ix=(rgD-lgD)*((x-ldgD)/(rdgD-ldgD))+lgD;
1481  iy=(tgD-bgD)*((y-bdgD)/(tdgD-bdgD))+bgD;
1482  LineTo(ix,iy);
1483
1484  cliplD=savel;
1485  cliprD=saver;
1486  cliptD=savet;
1487  clipbD=saveb;
1488}
1489
1490int PlotG(int mark,double x,double y)
1491{
1492  int ix,iy;
1493
1494  ix=(rgD-lgD)*((x-ldgD)/(rdgD-ldgD))+lgD;
1495  iy=(tgD-bgD)*((x-bdgD)/(tdgD-bdgD))+bgD;
1496  MoveTo(ix-1,iy-1);
1497  LineTo(ix-1,iy+1);
1498  LineTo(ix+1,iy+1);
1499  LineTo(ix-1,iy+1);
1500  LineTo(ix,iy+1);
1501  LineTo(ix,iy);
1502}
1503 
1504
1505int GifOutMin()
1506{
1507  int i,j,k;
1508  heiMin=10000;
1509  heiMax=-10000;
1510  widMin=10000;
1511  widMax=-10000;
1512  for(j=0;j<heightD;j++){
1513    for(i=0;i<widthD;i++){
1514      k=pD[widthD*j+i]; // CHARACTER
1515      if(k>0){
1516        if(i<widMin) widMin=i;
1517        if(i>widMax) widMax=i;
1518        if(j<heiMin) heiMin=j;
1519        if(j>heiMax) heiMax=j;
1520      }
1521    }
1522  }
1523  heiMax++;
1524  widMax++;
1525  i=GifOut();
1526  return i;
1527}
1528
1529int GifSaveMin(int n)
1530{
1531  int i,j,k;
1532  heiMin=10000;
1533  heiMax=-10000;
1534  widMin=10000;
1535  widMax=-10000;
1536  for(j=0;j<heightD;j++){
1537    for(i=0;i<widthD;i++){
1538      k=pD[widthD*j+i]; // CHARACTER
1539      if(k>0){
1540        if(i<widMin) widMin=i;
1541        if(i>widMax) widMax=i;
1542        if(j<heiMin) heiMin=j;
1543        if(j>heiMax) heiMax=j;
1544      }
1545    }
1546  }
1547  heiMax++;
1548  widMax++;
1549  GifSave(n);
1550  return 0;
1551}
1552
1553void outbyte1(int num,char *s)
1554{
1555  int i;
1556  unsigned char c;
1557  if(num<0){
1558    if(k64>0){
1559      out64[0]=b64digits[in64[0] >> 2];
1560      c=(in64[0] << 4) & 0x30;
1561      if (k64 > 1) c |= in64[1] >> 4;
1562      out64[1]=b64digits[c];
1563      out64[2] = (k64 < 2) ? '=' : b64digits[(in64[1] << 2) & 0x3c];
1564      out64[3] = '=';
1565      outbyte(4,out64);
1566    }
1567  }
1568  else{
1569    if(saveG==1||saveG==2||saveG==4) fwrite(s,sizeof(char),num,gfp);
1570    if(saveG==0||saveG==1) outbyte(num,s);
1571    if(saveG==3){
1572      for(i=0;i<num;i++){
1573        in64[k64]=s[i];
1574        k64++;
1575        if(k64==3){
1576          out64[0]=b64digits[in64[0] >> 2];
1577          out64[1]=b64digits[((in64[0] << 4) & 0x30) | (in64[1] >> 4)];
1578          out64[2]=b64digits[((in64[1] << 2) & 0x3c) | (in64[2] >> 6)];
1579          out64[3]=b64digits[in64[2] & 0x3f];
1580          outbyte(4,out64);
1581          k64=0;
1582          l64++;
1583          if(l64%18==0) outbyte(1,"\n");
1584        }
1585      }
1586    }
1587  }
1588
1589  return 0;
1590}
1591
1592int gifsize(int size)
1593{
1594  gsize=size;
1595  return 0;
1596}
1597
1598int GifOutMode(int mode)
1599{
1600  int i,j;
1601  i=0;
1602  switch(mode){
1603  case 3:
1604    saveG=3;
1605    break;
1606  case 4:
1607    gfp=fopen("/var/www/gcs/tmpnm","r");
1608    fscanf(gfp,"%i",&i);
1609    sprintf(saveGfn,"/var/www/gcs/tmp%02i.gif",i);
1610    fclose(gfp);
1611    j=i;
1612    j++;
1613    j%=10;
1614    gfp=fopen("/var/www/gcs/tmpnm","wb");
1615    fprintf(gfp,"%i\n",j);
1616    fclose(gfp);
1617    gfp=fopen(saveGfn,"wb");
1618    saveG=4;
1619    break;
1620  default:
1621    saveG=3;
1622    break;
1623  }
1624  return i;
1625}
1626
1627/**********************************************************************************
1628 GifOut
1629  saveG : 0 - out, 1 - out and save, 2 - save, 3 - base64, 4 - tmp
1630  pD1 : NULL - standard color table. pD[widthD*j+i];
1631        non-NULL - addaptive color table. (unsigned char)pD2->pixdata[widthD*j+i];
1632**********************************************************************************/
1633int GifOut()
1634{
1635  int i,j,k,l,o;
1636  unsigned char m;
1637  unsigned int step,red,green,blue;
1638
1639  int ctSize=256; /* may be overriden */
1640  int *prec;
1641  unsigned char *color;
1642  unsigned char pc[2000];
1643  int ipc,nn,n,nnstart,nstart;
1644  int bitsmin;
1645  int kstart;
1646  int clrcode;
1647  int wid,hei;
1648  int wid1,hei1;
1649  double ratio;
1650  int *nent;
1651  int r,g,b,r1,g1,b1;
1652
1653  if(pD1==NULL&&gsize!=1){ /* scaled output can be made only in the standard 256 colors */
1654    ratio=1./gsize;
1655    wid1=widMax-widMin;
1656    hei1=heiMax-heiMin;
1657    wid=wid1*ratio;
1658    hei=hei1*ratio;
1659    pD3=pcreate(4,wid,hei);
1660    k=wid*hei;
1661    nent=(int *)calloc(k,sizeof(int));
1662    for(j=0;j<hei1;j++){
1663      o=ratio*j;
1664      for(i=0;i<wid1;i++){
1665        l=ratio*i;
1666        k=pD[wid1*j+i];
1667        r=std256[k][1]/256;
1668        g=std256[k][2]/256;
1669        b=std256[k][3]/256;
1670        getpix(pD3,l,o,&r1,&g1,&b1);
1671        n=nent[o*wid+l];
1672        r=(r1*n+r)/(n+1);
1673        g=(g1*n+g)/(n+1);
1674        b=(b1*n+b)/(n+1);
1675        putpix(pD3,l,o,r,g,b);
1676        nent[o*wid+l]++;
1677      }
1678    }
1679    k=0;
1680    for(j=0;j<hei;j++){
1681      for(i=0;i<wid;i++){
1682        getpix(pD3,i,j,&r,&g,&b);
1683        pD[k++]=StdColorx(r*256,g*256,b*256);
1684      }
1685    }
1686    widMax=ratio*widMax;
1687    widMin=ratio*widMin;
1688    heiMax=ratio*heiMax;
1689    heiMin=ratio*heiMin;
1690    widthD=widMax-widMin;
1691  }
1692  wid=widMax-widMin;
1693  hei=heiMax-heiMin;
1694
1695  prec=(int *)malloc(4097*sizeof(int)); // code up to 12 bits
1696  color=(unsigned char*)malloc(4097*sizeof(unsigned char));
1697  for(i=0;i<4097;i++) prec[i]=-1;
1698
1699  outbyte1(6,"GIF89a");
1700  outbyte1(2,(char *)&wid);
1701  outbyte1(2,(char *)&hei);
1702
1703  if(pD1){
1704    switch(pD1->type){
1705    case 0:
1706      sizeOfCTD=0;
1707      ctSize=2;
1708      break;
1709    case 6:
1710      sizeOfCTD=1;
1711      ctSize=4;
1712      break;
1713    case 1:
1714    case 7:
1715      sizeOfCTD=3;
1716      ctSize=16;
1717      break;
1718    case 9:
1719    case 4:
1720      sizeOfCTD=7;
1721      ctSize=256;
1722      break;
1723    }
1724  }
1725  else sizeOfCTD=7;
1726  m=0xF0|sizeOfCTD;
1727  outbyte1(1,&m);
1728  m=0; // Background Color Index
1729  outbyte1(1,&m);
1730  m=0; // Pixel Aspect Ratio
1731  outbyte1(1,&m);
1732  if(pD1){
1733    if(pD1->type==4){
1734      pD2=pcreate(8,pD1->wid,pD1->hei); /* 8-bit non-standard index */
1735      cnvtype(pD1,pD2,2); /* reduce sparse */
1736      //  cnvtype(pD1,pD2,0); /* reduce dark */
1737      outbyte1(768,pD2->data);
1738    }
1739    else outbyte1(pD1->idxlen,pD1->data);
1740  }
1741  else{
1742    step=0xFFFF/5;
1743    for(i=5;i>=0;i--){
1744      red=i*step;
1745      for(j=5;j>=0;j--){
1746        green=j*step;
1747        for(k=5;k>=0;k--){
1748          blue=k*step;
1749          if(i!=0||j!=0||k!=0){
1750            outbyte1(1,(char *)&red);
1751            outbyte1(1,(char *)&green);
1752            outbyte1(1,(char *)&blue);
1753          }
1754        }
1755      }
1756    }
1757    step=0xFFFF/15;
1758    green=0;
1759    blue=0;
1760    for(i=14;i>0;i--){
1761      if(i%3!=0){
1762        red=i*step;
1763        outbyte1(1,(char *)&red);
1764        outbyte1(1,(char *)&green);
1765        outbyte1(1,(char *)&blue);
1766      }
1767    }
1768    red=0;
1769    blue=0;
1770    for(i=14;i>0;i--){
1771      if(i%3!=0){
1772        green=i*step;
1773        outbyte1(1,(char *)&red);
1774        outbyte1(1,(char *)&green);
1775        outbyte1(1,(char *)&blue);
1776      }
1777    }
1778    red=0;
1779    green=0;
1780    for(i=14;i>0;i--){
1781      if(i%3!=0){
1782        blue=i*step;
1783        outbyte1(1,(char *)&red);
1784        outbyte1(1,(char *)&green);
1785        outbyte1(1,(char *)&blue);
1786      }
1787    }
1788    for(i=14;i>0;i--){
1789      if(i%3!=0){
1790        red=green=blue=i*step;
1791        outbyte1(1,(char *)&red);
1792        outbyte1(1,(char *)&green);
1793        outbyte1(1,(char *)&blue);
1794      }
1795    }
1796    red=0;
1797    green=0;
1798    blue=0;
1799    outbyte1(1,(char *)&red);
1800    outbyte1(1,(char *)&green);
1801    outbyte1(1,(char *)&blue);
1802  }
1803  m=0x2c; // image separator
1804  outbyte1(1,&m);
1805  
1806  i=0; // image left position
1807  outbyte1(2,(char *)&i);
1808  i=0; // image top position
1809  outbyte1(2,(char *)&i);
1810  outbyte1(2,(char *)&wid);
1811  outbyte1(2,(char *)&hei);
1812  m=0x00|sizeOfCTD;
1813  outbyte1(1,&m);
1814
1815  m++; // LZW minimum code size 8
1816  if(m==1) m=2;
1817  outbyte1(1,&m);
1818  clrcode=1<<m; // clear code 0x100
1819  bitsD=m+1; // output number of bits
1820  bitsmin=bitsD; // initial number of bits
1821  for(i=0;i<ctSize;i++) color[i]=i; // the first 256 of 4097 colors
1822  for(i=0;i<260;i++) outBufD[i]=0;
1823  bitPtrD=0; // initialize output buffer
1824  emit(clrcode);
1825  ipc=0; // index for already-seen-color-sequence pc[]
1826  nnstart=0; // initial index value for nn used for pc[]
1827  nstart=clrcode+2; // n is index for preceeding code, prec
1828  for(j=heiMin;j<heiMax;j++){
1829    for(i=widMin;i<widMax;i++){
1830      if(pD1){
1831        switch(pD1->type){
1832        case 4:
1833          m=(unsigned char)pD2->pixdata[widthD*j+i];
1834          break;
1835        default:
1836          m=getpixid(pD1,i,j);
1837          break;
1838        }
1839      }
1840      else m=pD[widthD*j+i]; // CHARACTER
1841      pc[ipc++]=m; // STRING add to already-seen-sequence
1842      nn=nnstart; // index for pc[] used at comparing
1843      if(nn==0){ // first time and immediately after emit
1844        // for(k=0;k<ctSize;k++) if(color[k]==pc[nn]) break;
1845        k=pc[nn]; // equivalent to the above expression
1846        nn++;
1847      }
1848      else k=kstart; // code to be compared
1849      if(lzw){ // compress
1850        for(n=nstart;prec[n]!=-1;n++){ // matched upto and including nn-1 and n-1
1851          if(nn==ipc) break; // same as previously-seen-color-sequence
1852          if(prec[n]==k){
1853            if(color[n]==pc[nn]){
1854              nn++;
1855              k=n;
1856            }
1857          }
1858        }
1859        if(nn==ipc-1){ // if there is no previously-seen-color-sequence
1860          emit(k); // output code for hether-to matching sequence
1861          prec[n]=k; // add the code to dictionary
1862          color[n]=pc[ipc-1]; // add next-to-code-color in dictionary
1863          if(n>>bitsD) bitsD++;
1864          if(n==0xFFF){
1865            emit(clrcode);
1866            bitsD=bitsmin;
1867            for(n=0;n<4097;n++) prec[n]=-1;
1868          }
1869          pc[0]=m; // lastly-read color comes first in color array
1870          ipc=1;
1871          nnstart=0; //position of color array to be compared
1872          nstart=clrcode+2; // position of dictionary to be compared
1873        }
1874        else{ // when there is a previous instance
1875          nnstart=nn; // position of color array to be compared
1876          nstart=n; // position of dictionary to be compared
1877          kstart=k; // code to be compared
1878        }
1879      }
1880      else{ // not compress
1881        emit(m); // output code for hether-to matching sequence
1882        emit(clrcode);
1883        pc[0]=m; // lastly-read color comes first in color array
1884        ipc=1;
1885        nnstart=0; //position of color array to be compared
1886      }
1887    }
1888  }
1889  if(ipc==1){
1890    for(k=0;k<ctSize;k++) if(color[k]==pc[0]) break;
1891  }
1892  if(lzw) emit(k);
1893  n++;
1894  if(n>>bitsD) bitsD++;
1895
1896  emit(clrcode);
1897  bitsD=bitsmin;
1898
1899  emit(clrcode+1);
1900  i=bitPtrD/8;
1901  if((bitPtrD%8)!=0) i++;
1902  outbyte1(1,(char *)&i);
1903  outbyte1(i,(char *)outBufD);
1904  m=0;
1905  outbyte1(1,(char *)&m);
1906  m=0x3b;
1907  outbyte1(1,(char *)&m);
1908  outbyte1(-1,(char *)&m); /* for base64 encode */
1909  flush();
1910  if(saveG==4) fclose(gfp);
1911  //  delete[] prec;
1912  //  delete[] color;
1913
1914  return 0;
1915}
1916
1917
1918void emit(int k)
1919{
1920  int i,j,m,n;
1921
1922  for(i=0;i<bitsD;i++){ // do for current number of bits
1923    m=bitPtrD/8; // put in n-th bit of m-th byte
1924    n=bitPtrD%8;
1925    j=k;
1926    j>>=i;
1927    j&=1;
1928    j<<=n;
1929    outBufD[m]|=j; // outBuf is char , j is int
1930    bitPtrD++;
1931  }
1932
1933  if(m>254){
1934    i=0xFF;
1935    outbyte1(1,(char *)&i);
1936    outbyte1(255,(char *)outBufD);
1937
1938    bitPtrD-=255*8;
1939    outBufD[0]=outBufD[255];
1940    outBufD[1]=outBufD[256];
1941    for(i=2;i<257;i++) outBufD[i]=0;
1942  }
1943}
1944
1945int PngOut()
1946{
1947  unsigned char signa[]={137,80,78,71,13,10,26,10};
1948  unsigned char *chunk;
1949
1950  int i,j,k,l,m,n;
1951  int i1,j1,k1,l1,m1,n1;
1952  int i2,j2,k2,l2,m2,n2;
1953  unsigned int step,red,green,blue;
1954  int lmatch,dmatch;
1955  int wdopen;
1956  unsigned long adler=1L;
1957  unsigned long s1,s2;
1958
1959  i=widthD*heightD/10;
1960  chunk=(unsigned char *)calloc(i*sizeof(char),sizeof(char)); /* this size must be related to picture size */
1961  
1962
1963  outbyte(8,(char *)signa);
1964
1965  *(int *)&chunk[0]=13; // excluding length, type or crc
1966  revPng(&chunk[0]);
1967  chunk[4]='I';
1968  chunk[5]='H';
1969  chunk[6]='D';
1970  chunk[7]='R';
1971  *(int *)&chunk[8]=widthD;
1972  revPng(&chunk[8]);
1973  *(int *)&chunk[12]=heightD;
1974  revPng(&chunk[12]);
1975  chunk[16]=8; /* bit depth */
1976  chunk[17]=3; /* color type - palette index */
1977  chunk[18]=0; /* compression method - deflate */
1978  chunk[19]=0; /* filter method */
1979  chunk[20]=0; /* interlace method */
1980  crcPng(&chunk[4],17); // including chunk type and chunk data
1981  outbyte(25,(char *)chunk);
1982  *(int *)&chunk[0]=768; // 256*3
1983  revPng(&chunk[0]);
1984  chunk[4]='P';
1985  chunk[5]='L';
1986  chunk[6]='T';
1987  chunk[7]='E';
1988  l=8;
1989  step=0xFFFF/5;
1990  for(i=5;i>=0;i--){
1991    red=i*step;
1992    for(j=5;j>=0;j--){
1993      green=j*step;
1994      for(k=5;k>=0;k--){
1995        blue=k*step;
1996        if(i!=0||j!=0||k!=0){
1997          chunk[l++]=red;
1998          chunk[l++]=green;
1999          chunk[l++]=blue;
2000        }
2001      }
2002    }
2003  }
2004  step=0xFFFF/15;
2005  green=0;
2006  blue=0;
2007  for(i=14;i>0;i--){
2008    if(i%3!=0){
2009      red=i*step;
2010      chunk[l++]=red;
2011      chunk[l++]=green;
2012      chunk[l++]=blue;
2013    }
2014  }
2015  red=0;
2016  blue=0;
2017  for(i=14;i>0;i--){
2018    if(i%3!=0){
2019      green=i*step;
2020      chunk[l++]=red;
2021      chunk[l++]=green;
2022      chunk[l++]=blue;
2023    }
2024  }
2025  red=0;
2026  green=0;
2027  for(i=14;i>0;i--){
2028    if(i%3!=0){
2029      blue=i*step;
2030      chunk[l++]=red;
2031      chunk[l++]=green;
2032      chunk[l++]=blue;
2033    }
2034  }
2035  for(i=14;i>0;i--){
2036    if(i%3!=0){
2037      red=green=blue=i*step;
2038      chunk[l++]=red;
2039      chunk[l++]=green;
2040      chunk[l++]=blue;
2041    }
2042  }
2043  red=0;
2044  green=0;
2045  blue=0;
2046  chunk[l++]=red;
2047  chunk[l++]=green;
2048  chunk[l++]=blue;
2049  crcPng(&chunk[4],768+4);
2050  outbyte(780,(char *)chunk);
2051  for(l=0;l<780;l++) chunk[l]=0;
2052  /** LZ77 conpression **/
2053  chunk[4]='I';
2054  chunk[5]='D';
2055  chunk[6]='A';
2056  chunk[7]='T';
2057  chunk[8]=0x78; /* compression method/flag code */
2058  chunk[9]=0x9c; /* additional flags/check bits */
2059  i1=10; // initial code byte
2060  j1=0; // initial bit position
2061  setPng(chunk,i1,j1,3,3,&i1,&j1); // three header bit for the block
2062                                   // final & fixed Huffman code
2063  l=heightD*widthD; /* insert filter type byte */
2064  for(n=heightD-1;n>=0;n--){
2065    k=n*(widthD+1);
2066    for(m=widthD;m>0;m--) pD[k+m]=pD[--l];
2067    pD[k]=0;
2068  }
2069  wdopen=0;
2070  l=heightD*(widthD+1);
2071  for(n=0;n<l;n++){
2072    lmatch=0;
2073    if(n<32768) wdopen=0;
2074    else wdopen=n-32768;
2075    for(m=n-1;m>=wdopen;m--){
2076      j=n;
2077      k=m;
2078      i=0;
2079      while(pD[j++]==pD[k++]){
2080        i++;
2081        if(i==258) break;
2082        if(j>=l) break;
2083      }
2084      if(i>lmatch){
2085        lmatch=i; /* length */
2086        dmatch=n-m; /* distance */
2087      }
2088      if(lmatch==258||j>=l) break;
2089    }
2090    l1=0; // number of extra bits
2091    m1=0; // value of extra bits
2092    if(lmatch<3) k1=pD[n];  // raw data
2093    else{
2094      if(lmatch<11) k1=254+lmatch;
2095      else if(lmatch<19){
2096        l1=1;
2097        k1=(lmatch-11)/2+265;
2098        m1=(lmatch-11)%2;
2099      }
2100      else if(lmatch<35){
2101        l1=2;
2102        k1=(lmatch-19)/4+269;
2103        m1=(lmatch-19)%4;
2104      }
2105      else if(lmatch<67){
2106        l1=3;
2107        k1=(lmatch-35)/8+273;
2108        m1=(lmatch-35)%8;
2109      }
2110      else if(lmatch<131){
2111        l1=4;
2112        k1=(lmatch-67)/16+277;
2113        m1=(lmatch-67)%16;
2114      }
2115      else if(lmatch<258){
2116        l1=5;
2117        k1=(lmatch-131)/32+281;
2118        m1=(lmatch-131)%32;
2119      }
2120      else k1=285;
2121    } /* else */
2122    /* convert alphabet k1 to Huffman code */
2123    if(k1<144){
2124      n1=0x30+k1; // Huffman code
2125      i2=0x80; // mask for output
2126    }
2127    else if(k1<256){
2128      n1=0x190+k1-144;
2129      i2=0x100;
2130    }
2131    else if(k1<280){
2132      n1=0x0+k1-256;
2133      i2=0x40;
2134    }
2135    else{
2136      n1=0xc0+k1-280;
2137      i2=0x80;
2138    }
2139    for(;i2>0;i2/=2){
2140      if(n1&i2) setPng(chunk,i1,j1,1,1,&i1,&j1);
2141      else setPng(chunk,i1,j1,0,1,&i1,&j1);
2142    }
2143    if(l1>0) setPng(chunk,i1,j1,m1,l1,&i1,&j1); /* extra bits for length */
2144    if(k1>256){ /* distance in dmatch */
2145      m2=1;
2146      for(l2=1;;l2++){
2147        m2*=2;
2148        if(m2>=dmatch) break;
2149      }
2150      k1=l2*2-1; // code 
2151      //     dmatch<= k1 l2 extra-bits
2152      //        2      1   1    0
2153      //        4      3   2    0
2154      //        8      5   3    1
2155      //       16      7   4    2
2156      //       32      9   5    3
2157      l1=l2-2;   // number of extra bits
2158      if(l1<0) l1=0;
2159      // m2       2   2   4   4   8   8   8   8  16  16  16
2160      // dmatch   1   2   3   4   5   6   7   8   9  10  11
2161      // l2       1   1   2   2   3   3   3   3   4   4   4
2162      // k1       1   1   3   3   5   5   5   5   7   7   7
2163      // l1       0   0   0   0   1   1   1   1   2   2   2 ->number of extra bits
2164      // n2       1   1   1   1   2   2   2   2   4   4   4
2165      // m2-n2    1   1   3   3   6   6   6   6  12  12  12
2166      // k1       0  (1)  2  (3)  4   4  (5) (5)  6   6   6 ->code
2167      // m2       1   2   3   4   6   6   8   8  12  12  12
2168      // m2-n2    0   1   2   3   4   4   6   6   8   8   8
2169      // m1       1   1   1   1   1   2   1   2   1   2   3
2170      // m1       0   0   0   0   0   1   0   1   0   1   2 ->extra bit value
2171      n2=pow(2,l1);
2172      if(dmatch<=m2-n2){
2173        k1--;
2174        m2=m2-n2;
2175      }
2176      m1=dmatch-(m2-n2);
2177      m1--;    // value of extra bits
2178
2179      i2=0x10; // 5 bits
2180      for(;i2>0;i2/=2){
2181        if(k1&i2) setPng(chunk,i1,j1,1,1,&i1,&j1);
2182        else setPng(chunk,i1,j1,0,1,&i1,&j1);
2183      }
2184      if(l1>0) setPng(chunk,i1,j1,m1,l1,&i1,&j1); /* extra bits for distance */
2185      n+=lmatch-1; /* advance main loop counter - 1 incremented later */
2186    } /* if(k1>256) */
2187  } /* for(n=0;n<l;n++){ */
2188  i2=0x40; // 7 bits - end of block mark
2189  for(;i2>0;i2/=2){ // huffman code for 256 is 0
2190    if(0&i2) setPng(chunk,i1,j1,1,1,&i1,&j1);
2191    else setPng(chunk,i1,j1,0,1,&i1,&j1);
2192  }
2193  /* Adler-32 : a check sum value of the uncompressed data */
2194  s1=adler&0xffff;
2195  s2=(adler>>16)&0xffff;
2196  for(n=0;n<l;n++){
2197    s1=(s1+pD[n])%65521;
2198    s2=(s2+s1)%65521;
2199  }
2200  if(j1!=0) i1++;
2201  *(unsigned long *)&chunk[i1]=(s2<<16)+s1;
2202  revPng(&chunk[i1]);
2203  i1+=4;  /* pointer index to crc */
2204  *(int *)&chunk[0]=i1-8; /* data length */
2205  revPng(&chunk[0]);
2206  crcPng(&chunk[4],i1-4);
2207  i1+=4; /* number of bytes including crc */
2208  outbyte(i1,(char *)chunk);
2209  *(int *)&chunk[0]=0; /* data length */
2210  revPng(&chunk[0]);
2211  chunk[4]='I';
2212  chunk[5]='E';
2213  chunk[6]='N';
2214  chunk[7]='D';
2215  crcPng(&chunk[4],4);
2216  outbyte(12,(char *)chunk);
2217  flush();
2218
2219}
2220
2221void revPng(unsigned char *c)
2222{
2223  unsigned char a;
2224  a=c[0];
2225  c[0]=c[3];
2226  c[3]=a;
2227  a=c[1];
2228  c[1]=c[2];
2229  c[2]=a;
2230}
2231
2232/*********************************************
2233  Pad data into chunk
2234  chunk : chunk array
2235  byte : index into chunk array
2236  bit : bit position (0(lsb)-7(msb))
2237  val : data to be set
2238  nbit : number of bits of val
2239  *nxtbyte : next index to be returned
2240  *nxtbit : next bit position to be returned
2241  ********************************************/
2242void setPng(unsigned char *chunk,int byte,int bit,
2243            int val,int nbit,int *nxtbyte,int *nxtbit)
2244{
2245  unsigned char c1,c2;
2246  unsigned char cin[4];
2247  unsigned char mask,mask1;
2248  int sourcebyte,destbyte,sourcebit,destbit;
2249  int i;
2250
2251  sourcebyte=0;
2252  sourcebit=0;
2253  destbyte=byte;
2254  destbit=bit;
2255  *(unsigned long*)cin=val;
2256  for(i=0;i<nbit;i++){
2257    mask=1;
2258    mask<<=sourcebit;
2259    c1=cin[sourcebyte];
2260    if(c1&mask){
2261      mask=1;
2262      mask<<=destbit;
2263      chunk[destbyte]|=mask;
2264    }
2265    sourcebit++;
2266    if(sourcebit==8){
2267      sourcebyte++;
2268      sourcebit=0;
2269    }
2270    destbit++;
2271    if(destbit==8){
2272      destbyte++;
2273      destbit=0;
2274    }
2275  }
2276  *nxtbyte=destbyte;
2277  *nxtbit=destbit;
2278}
2279
2280
2281/**********************************************
2282  CRC - ported from W3C specification
2283  Return the CRC of the bytes buf[0]..[len-1]
2284  in buf[len]..[len+3] 
2285**********************************************/
2286void crcPng(unsigned char *buf,int len)
2287{
2288  unsigned long c;
2289  int n,k;
2290
2291  if(!crc_table_computed){
2292    for(n=0;n<256;n++){
2293      c=(unsigned long)n;
2294      for(k=0;k<8;k++){
2295        if(c&1) c=0xedb88320L^(c>>1);
2296        else c=c>>1;
2297      }
2298      crc_table[n]=c;
2299    }
2300    crc_table_computed=1;
2301  }
2302  c=0xffffffffL;
2303  for(n=0;n<len;n++){
2304    c=crc_table[(c^buf[n])&0xff]^(c>>8);
2305  }
2306  *(int *)&buf[len]=c^0xffffffffL;
2307  revPng(&buf[len]);
2308}
2309
2310/**************************************************
2311 r,g,b - 0-100
2312**************************************************/
2313int WritePixel(int x,int y,int r,int g, int b)
2314{
2315  int i;
2316  if(x<cliplD) return; // clip rect left
2317  if(x>=cliprD) return;
2318  if(y<cliptD) return;
2319  if(y>=clipbD) return;
2320  if(pD1) putpix(pD1,x,y,r,g,b);
2321  else{
2322    i=StdColor(r,g,b);
2323    *(pD+y*widthD+x)=i;
2324  }
2325}
2326
2327int WritePixel1(int xoff,int yoff)
2328{
2329  int x,y;
2330  x=xD+xoff;
2331  y=yD+yoff;
2332  if(x<cliplD) return; // clip rect left
2333  if(x>=cliprD) return;
2334  if(y<cliptD) return;
2335  if(y>=clipbD) return;
2336  if(pD1){
2337    if(pD1->type==4) putpix(pD1,x,y,rD1,gD1,bD1);
2338    else putpixid(pD1,x,y,coloD);
2339  }
2340  else *(pD+y*widthD+x)=coloD;
2341}
2342
2343
2344/***************************************************
2345 frac - 0-255
2346***************************************************/
2347int WritePixel2(int xoff,int yoff,int frac)
2348{
2349  int x,y,r,g,b,r1,g1,b1,r2,g2,b2,co1,col1;
2350  x=xD+xoff;
2351  y=yD+yoff;
2352  if(x<cliplD) return; // clip rect left
2353  if(x>=cliprD) return;
2354  if(y<cliptD) return;
2355  if(y>=clipbD) return;
2356  if(pD1){
2357    getpix(pD1,x,y,&r1,&g1,&b1);
2358    r2=rD1;
2359    g2=gD1;
2360    b2=bD1;
2361    r=(r1*(255-frac)+r2*frac)/255;
2362    g=(g1*(255-frac)+g2*frac)/255;
2363    b=(b1*(255-frac)+b2*frac)/255;
2364    putpix(pD1,x,y,r,g,b);
2365  }
2366  else{
2367    col1=*(pD+y*widthD+x);
2368    r1=std256[col1][1];
2369    g1=std256[col1][2];
2370    b1=std256[col1][3];
2371    r2=std256[coloD][1];
2372    g2=std256[coloD][2];
2373    b2=std256[coloD][3];
2374    r=(r1*(255-frac)+r2*frac)/255;
2375    g=(g1*(255-frac)+g2*frac)/255;
2376    b=(b1*(255-frac)+b2*frac)/255;
2377    *(pD+y*widthD+x)=StdColorx(r,g,b);
2378  }
2379}
2380
2381int WritePixel3(int x,int y,int argb)
2382{
2383  int a,r,g,b,r1,g1,b1,r2,g2,b2,i;
2384  getpix(pD1,x,y,&r1,&g1,&b1);
2385  a=(argb>>24)&0xff;
2386  r2=(argb>>16)&0xff;
2387  g2=(argb>>8)&0xff;
2388  b2=argb&0xff;
2389  r=(r1*(255-a)+r2*a)/255;
2390  g=(g1*(255-a)+g2*a)/255;
2391  b=(b1*(255-a)+b2*a)/255;
2392  putpix(pD1,x,y,r,g,b);
2393}
2394
2395int WritePixelId(int x,int y,int i)
2396{
2397  if(pD1)
2398    putpixid(pD1,x,y,i);
2399  else
2400    *(pD+y*widthD+x)=i;
2401  return 0;
2402}
2403 
2404int ReadPixelId(int x,int y)
2405{
2406  int i;
2407  if(pD1)
2408    i=getpixid(pD1,x,y);
2409  else
2410    i=*(pD+y*widthD+x);
2411  return i;
2412}
2413  
2414/***************************************************
2415 standard color index
2416 r1,g1,b1 - 0-100
2417***************************************************/
2418int StdColor(int r1,int g1,int b1)
2419{
2420  int i;
2421  int r,g,b;
2422  
2423  r=r1*(0xffff/100);
2424  g=g1*(0xffff/100);
2425  b=b1*(0xffff/100);
2426  return StdColorx(r,g,b);
2427}
2428
2429int StdColorx(int r,int g,int b)
2430{
2431  int i;
2432
2433  if(r==0&&g==0&&b==0){
2434    return 255;
2435  }
2436  if(r==0xffff&&g==0xffff&&b==0xffff){
2437    return 0;
2438  }
2439  if(r==0&&g==0){
2440    i=(b+2185)/4369;
2441    if(i%3!=0){
2442      return 245-(i-i/3);
2443    }
2444  }
2445  if(g==0&&b==0){
2446    i=(r+2185)/4369;
2447    if(i%3!=0){
2448      return 225-(i-i/3);
2449    }
2450  }
2451  if(b==0&&r==0){
2452    i=(g+2185)/4369;
2453    if(i%3!=0){
2454      return 235-(i-i/3);
2455    }
2456  }
2457  if(b==g&&r==g){ // gray scale
2458    i=(g+2185)/4369;
2459    if(i!=0&&i%3!=0){
2460      return 255-(i-i/3);
2461    }
2462  }
2463  i=215-((r+6554)/13107)*36-((g+6554)/13107)*6-(b+6554)/13107;
2464  if(i==215) i=255;
2465  return i;
2466}
2467
2468void GifPatent() /* no more used */
2469{
2470  lzw=1;
2471}
2472
2473void ChangeSize(int deno)
2474{
2475  int i,j,k,l,m,n;
2476  int r,g,b;
2477
2478  widMin=0;
2479  widMax=widthD/2;
2480  heiMin=0;
2481  heiMax=heightD/2;
2482  for(j=0;j<heiMax;j++){
2483    for(i=0;i<widMax;i++){
2484      k=pD[widthD*j*2+i*2];
2485      l=pD[widthD*j*2+i*2+1];
2486      m=pD[widthD*(j*2+1)+i*2];
2487      n=pD[widthD*(j*2+1)+i*2+1];
2488      if(k==l&&l==m&&m==n){
2489        pD[widthD*j+i]=k;
2490      }
2491      else{
2492        r=(std256[k][1]+std256[l][1]+std256[m][1]+std256[n][1])/4;
2493        g=(std256[k][2]+std256[l][2]+std256[m][2]+std256[n][2])/4;
2494        b=(std256[k][3]+std256[l][3]+std256[m][3]+std256[n][3])/4;
2495        pD[widthD*j+i]=StdColorx(r,g,b);
2496      }
2497    }
2498  }
2499  i=GifOut();
2500}
2501
2502void GifSave(int num)
2503{
2504  double ratio;
2505  FILE *fp;
2506  int i,j,k,l,m,n;
2507  int *nent;
2508  int r,g,b,r1,g1,b1;
2509  int wid,hei;
2510  int wid1,hei1;
2511
2512  saveG=1; /* output and save */
2513  saveG=2;
2514  strcpy(saveGfn,"pc/o"); /* original */
2515  sprintf(&saveGfn[4],"%04i",num);
2516  strcat(saveGfn,".gif");
2517  gfp=fopen(saveGfn,"wb");
2518  GifOut();
2519  fclose(gfp);
2520  saveG=2; /* save */
2521  saveG=1;
2522  if(widthD*heightD<3000){ /* the original is smaller than thumbnail */
2523    gfp=fopen(saveGfn,"rb");
2524    saveGfn[3]='t';
2525    fp=fopen(saveGfn,"wb");
2526    while((i=fgetc(gfp))!=EOF) fputc(i,fp);
2527    fclose(fp);
2528    fclose(gfp);
2529    outbyte(16,"thumbnail saved\n");
2530    flush();
2531    return;
2532  }
2533  ratio=3000./(widthD*heightD);
2534  ratio=sqrt(ratio);
2535  wid=ratio*widthD;
2536  hei=ratio*heightD;
2537  widMin=0;
2538  widMax=wid;
2539  heiMin=0;
2540  heiMax=hei;
2541  wid1=widthD;
2542  hei1=heightD;
2543  widthD=wid;
2544  heightD=hei;
2545
2546  pD3=pcreate(4,wid,hei);
2547  k=wid*hei;
2548  nent=(int *)calloc(k,sizeof(int));
2549  if(pD1){
2550    for(j=0;j<hei1;j++){
2551      m=ratio*j;
2552      if(m==hei) m--;
2553      for(i=0;i<wid1;i++){
2554        l=ratio*i;
2555        if(l==wid) l--;
2556        getpix(pD1,i,j,&r,&g,&b);
2557        getpix(pD3,l,m,&r1,&g1,&b1);
2558        n=nent[m*wid+l];
2559        r=(r1*n+r)/(n+1);
2560        g=(g1*n+g)/(n+1);
2561        b=(b1*n+b)/(n+1);
2562        putpix(pD3,l,m,r,g,b);
2563        nent[m*wid+l]++;
2564      }
2565    }
2566  }
2567  else{
2568    for(j=0;j<hei1;j++){
2569      m=ratio*j;
2570      if(m==hei) m--;
2571      for(i=0;i<wid1;i++){
2572        l=ratio*i;
2573        if(l==wid) l--;
2574        k=pD[wid1*j+i];
2575        r=std256[k][1]/256;
2576        g=std256[k][2]/256;
2577        b=std256[k][3]/256;
2578        getpix(pD3,l,m,&r1,&g1,&b1);
2579        n=nent[m*wid+l];
2580        r=(r1*n+r)/(n+1);
2581        g=(g1*n+g)/(n+1);
2582        b=(b1*n+b)/(n+1);
2583        putpix(pD3,l,m,r,g,b);
2584        nent[m*wid+l]++;
2585      }
2586    }
2587  }  
2588  if(pD1){
2589    free(pD1);
2590    free(pD2);
2591  }
2592  pD1=pD3;
2593
2594  strcpy(saveGfn,"pc/t"); /* thumbnail */
2595  sprintf(&saveGfn[4],"%04i",num);
2596  strcat(saveGfn,".gif");
2597  gfp=fopen(saveGfn,"wb");
2598  GifOut();
2599  fclose(gfp);
2600}
2601
2602void GifOutFile(char *s)
2603{
2604  saveG=1; /* output and save */
2605  strcpy(saveGfn,"/var/gcs/usr/");
2606  strcat(saveGfn,s);
2607  strcat(saveGfn,"XXXXXX");
2608  mktemp(saveGfn);
2609  outbyte(3,"add");
2610  outbyte(10,&saveGfn[13]);
2611  flush();
2612  gfp=fopen(saveGfn,"wb");
2613  GifOut();
2614  fclose(gfp);
2615}
2616
2617int GifPaste(char *s,int left,int top)
2618{
2619  char *ck;
2620  char fn[30];
2621  int i,j,k,l,m;
2622  unsigned char *p;
2623  int done;
2624  int endcode;
2625  unsigned char ccode;
2626  int x,y;
2627
2628  ck=getenv("HTTP_COOKIE");
2629  if(ck==0) return -1;
2630  for(i=5;i<500;i+=10){
2631    if(ck[i]=='\0') return -1;
2632    for(j=0;j<4;j++) if(ck[i+j]!=s[j]) break;
2633    if(j==4) break;
2634  }
2635  if(j!=4) return -1;
2636  strcpy(fn,"/var/gcs/usr/");
2637  for(j=0;j<10;j++) fn[13+j]=ck[i+j];
2638  fn[13+j]='\0';
2639  if((infile =  fopen(fn, "rb"))==NULL) return -1;
2640  if(pD1);
2641  else p=pD;
2642  prec=(int *)malloc(sizeof(int)*4097);
2643  color=(unsigned char *)malloc(sizeof(char)*4097);
2644  cbuff=(unsigned char *)malloc(sizeof(char)*4097);
2645  fread(buff,sizeof(char),6,infile); // read header GIF89a
2646  if(buff[0]!=0x47) return -1;
2647  fread(buff,sizeof(char),4,infile); // screen width and height
2648  l=*(short *)&buff[0]; // width
2649  m=0;
2650  fread(buff,sizeof(char),1,infile); // packed fields
2651  i=buff[0]&0x07;
2652  j=pow(2,i+1); // size of Global Color Table
2653  fread(buff,sizeof(char),2,infile); // Background Color Index, Pixel Aspect Ratio
2654  for(i=0;i<j;i++)
2655    fread(buff,sizeof(char),3,infile);
2656  do{
2657    fread(buff,sizeof(char),1,infile);
2658    done=0;
2659    switch(buff[0]){
2660    case 0x2c:
2661      fread(buff,sizeof(char),4,infile); // left position etc
2662      fread(buff,sizeof(char),4,infile); // width etc
2663      fread(buff,sizeof(char),1,infile); // local color table, interlace
2664      /* local color table assumed to be absent */
2665      fread(buff,sizeof(char),1,infile); // LZW minimum code size
2666      i=buff[0];
2667      clrcode=1<<i;
2668      endcode=clrcode+1; // end-of-information code
2669      bits=buff[0]+1;
2670      bitsmin=bits;
2671      //  nxtCode=clrcode+2;
2672      nxtCode=clrcode+1;
2673      pteByte=2;
2674      bitPtrMax=0;
2675      bitPtr=16;
2676      TermRead=0;
2677      while((newCode=collect())!=endcode){
2678        if(nxtCode==clrcode+1){
2679          oldCode=newCode;
2680          ccode=oldCode;
2681          if(pD1){
2682            putpixid(pD1,m%l+left,m/l+top,ccode);
2683            m++;
2684          }
2685          else{
2686            x=m%l+left;
2687            y=m/l+top;
2688            if(x>=0&&x<widthD&&y>=0&&y<heightD)
2689              p[y*widthD+x]=ccode;
2690            m++;
2691          }
2692          nxtCode++;
2693        }
2694        else{
2695          if(newCode>=nxtCode){
2696            cbuff[4096]=ccode;
2697            i=decode(4095,oldCode);
2698          }
2699          else i=decode(4096,newCode);
2700          for(j=i;j<4097;j++){
2701            if(pD1){
2702              putpixid(pD1,m%l+left,m/l+top,cbuff[j]);
2703              m++;
2704            }
2705            else{
2706              x=m%l+left;
2707              y=m/l+top;
2708              if(x>=0&&x<widthD&&y>=0&&y<heightD)
2709               p[y*widthD+x]=cbuff[j];
2710              m++;
2711            }
2712          }
2713          ccode=cbuff[i];
2714          prec[nxtCode]=oldCode;
2715          color[nxtCode]=ccode;
2716          nxtCode++;
2717          if(nxtCode>>bits) bits++;
2718          oldCode=newCode;
2719        }
2720      }
2721      if(TermRead==0) fread(buff,sizeof(char),1,infile);
2722      break;
2723    case 0x21: // extension introducer
2724      fread(buff,sizeof(char),1,infile);
2725      switch (buff[0]){
2726      case 0xf9: // Graphic Control Label
2727        buff[1]=0;
2728        fread(&buff[0],sizeof(char),1,infile);
2729        j=*(short *)&buff[0];
2730        fread(buff,sizeof(char),j,infile);
2731        j=buff[0];
2732        j&=0x1c;
2733        j>>=2;
2734        fread(&buff[0],sizeof(char),1,infile); // block terminator
2735        break;
2736      case 0xfe: // Comment Label
2737        while(1){
2738          fread(buff,sizeof(char),1,infile);
2739          j=*(unsigned char *)buff;
2740          if(j==0) break;
2741          fread(buff,sizeof(char),j,infile);
2742        }
2743        break;
2744      case 0x01: // Plain Text Label
2745        while(1){
2746          fread(buff,sizeof(char),1,infile);
2747          j=*(unsigned char *)buff;
2748          if(j==0) break;
2749          fread(buff,sizeof(char),j,infile);
2750        }
2751        break;
2752      case 0xff: // Application Label
2753        while(1){
2754          fread(buff,sizeof(char),1,infile);
2755          j=*(unsigned char *)buff;
2756          if(j==0) break;
2757          fread(buff,sizeof(char),j,infile);
2758        }
2759        break;
2760      default:
2761        done=1;
2762        break;
2763      }
2764      break;
2765    case 0x3b:
2766      done=1;
2767      break;
2768    default:
2769      done=1;
2770      break;
2771    }
2772  } while(!done);
2773  fclose(infile);
2774}
2775
2776 
2777/******************************************************************************
2778    collect a token from compressed picture data
2779
2780 unsigned char inBuf[260];
2781 int bitPtr;
2782 int bitPtrMax; // bit pointer mark for supplying new data
2783 int pteByte;   // past-the-end index into inBuf[]
2784 int bits;
2785 int TermRead;
2786
2787 set initial bitPtr to 16
2788 set initial bitPtrMax to 0
2789 set initial pteByte to 2
2790 if bitPtr upon entry >= bitPtrMax,
2791   inBuf[pteByte-2] and inBuf[pteByte-1] will
2792   be moved to inBuf[0] and inBuf[1].
2793   new block of data will be read into area beginning inBuf[2]
2794   bitPtr will be decreased by bitPtrMax
2795   bitPtrMax will be set to (read bytes * 8)
2796 There will be 2 cases when the End-of-Information code is returned.
2797   case 1 : Block terminator was read
2798   case 2 : Block terminator is yet to be read
2799   To detect which case actually occurred, set TermRead to 0.
2800   If it has changed to 1, case 1 occurred.
2801*****************************************************************************/
2802int collect()
2803{
2804  int i,j,m,n,k;
2805  unsigned int ui;
2806  unsigned char c;
2807
2808  if(bitPtr>=bitPtrMax){
2809    inBuf[0]=inBuf[pteByte-2];
2810    inBuf[1]=inBuf[pteByte-1];
2811    fread(&c,sizeof(char),1,infile);
2812    ui=c;
2813    i=ui;
2814    if(i==0) TermRead=1;
2815    else fread(&inBuf[2],sizeof(char),i,infile);
2816    bitPtr-=bitPtrMax;
2817    pteByte=2+i;
2818    bitPtrMax=8*(pteByte-2);
2819  }
2820  k=0;
2821  for(i=0;i<bits;i++){
2822    m=bitPtr/8;
2823    n=bitPtr%8;
2824    j=inBuf[m];
2825    j>>=n;
2826    j&=1;
2827    j<<=i;
2828    k|=j;
2829    bitPtr++;
2830  }
2831  if(k==clrcode){
2832    nxtCode=clrcode+1;
2833    bits=bitsmin;
2834    k=collect();
2835  }
2836  return k;
2837}
2838
2839/**************************************************************
2840  decode to buffer
2841**************************************************************/
2842int decode(int i,int code)
2843{
2844  while(code>clrcode){
2845    cbuff[i--]=color[code];
2846    code=prec[code];
2847  }
2848  cbuff[i]=code;
2849  return i;
2850}
2851