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