draw1.c
0000#include <stdio.h>
0001#include <stdlib.h>
0002#include <string.h>
0003#include <math.h>
0004#include "draw1.h"
0005#include "draw7.h"
0006#include "gcs1.h"
0007
0008int outbyte(int num,char *buf);
0009int flush();
0010
0011/**************** basic draw information ***********/
0012unsigned char* pD; // bitmap buffer
0013int depthD; // Mac standard 256 colors
0014int widthD; // picture size
0015int heightD;
0016int coloD; // current color for drawing
0017int xD; // current pen position
0018int yD;
0019int cliplD; // clip rect left
0020int cliprD;
0021int cliptD;
0022int clipbD;
0023
0024/**************** for polygon ***************/
0025unsigned char* poD; // bitmap buffer
0026int polyWidthD; // number of chars for one line of poD
0027int firstPtxD; // x value of first point. saved for closure
0028int firstPtyD;
0029int vertXD; // left-upper line crossings
0030int horiXD; // upper-left line crossings
0031int polyD; // 1 if polygon mode
0032int pxminD,pxmaxD,pyminD,pymaxD; // bounding rect
0033
0034/***************** for font ********************/
0035unsigned char* pfD; // font bitmap
0036int fontD; // font id (11,16,22)
0037int direcD; // direction of string 0:horiz 1:vert
0038int modeD; // current pen position is 0:left 1:right 2:center of string
0039int widthBytesD;
0040int fontBytesD;
0041int ascentD;
0042int descentD;
0043int fontWidthD;
0044int fontHeightD;
0045#include "font.c"
0046
0047/***************** for graph ********************/
0048int lgD,tgD,rgD,bgD;
0049double ldgD,tdgD,rdgD,bdgD;
0050int htD,hlD,vlD;
0051
0052/**************** output ***********************/
0053int widMin,widMax,heiMin,heiMax;
0054int lzw=1; // compress
0055unsigned char sizeOfCTD; // depthD-1
0056unsigned char outBufD[260];
0057int bitPtrD;
0058int bitsD;
0059FILE *fpD;
0060int gsize=1; // gif scale
0061
0062/**************** for CRC ********************/
0063unsigned long crc_table[256];
0064int crc_table_computed=0;
0065
0066/************* color table ******************/
0067int std256[256][4]={
00680,65535,65535,65535,
00691,65535,65535,52428,
00702,65535,65535,39321,
00713,65535,65535,26214,
00724,65535,65535,13107,
00735,65535,65535, 0,
00746,65535,52428,65535,
00757,65535,52428,52428,
00768,65535,52428,39321,
00779,65535,52428,26214,
007810,65535,52428,13107,
007911,65535,52428, 0,
008012,65535,39321,65535,
008113,65535,39321,52428,
008214,65535,39321,39321,
008315,65535,39321,26214,
008416,65535,39321,13107,
008517,65535,39321, 0,
008618,65535,26214,65535,
008719,65535,26214,52428,
008820,65535,26214,39321,
008921,65535,26214,26214,
009022,65535,26214,13107,
009123,65535,26214, 0,
009224,65535,13107,65535,
009325,65535,13107,52428,
009426,65535,13107,39321,
009527,65535,13107,26214,
009628,65535,13107,13107,
009729,65535,13107, 0,
009830,65535, 0,65535,
009931,65535, 0,52428,
010032,65535, 0,39321,
010133,65535, 0,26214,
010234,65535, 0,13107,
010335,65535, 0, 0,
010436,52428,65535,65535,
010537,52428,65535,52428,
010638,52428,65535,39321,
010739,52428,65535,26214,
010840,52428,65535,13107,
010941,52428,65535, 0,
011042,52428,52428,65535,
011143,52428,52428,52428,
011244,52428,52428,39321,
011345,52428,52428,26214,
011446,52428,52428,13107,
011547,52428,52428, 0,
011648,52428,39321,65535,
011749,52428,39321,52428,
011850,52428,39321,39321,
011951,52428,39321,26214,
012052,52428,39321,13107,
012153,52428,39321, 0,
012254,52428,26214,65535,
012355,52428,26214,52428,
012456,52428,26214,39321,
012557,52428,26214,26214,
012658,52428,26214,13107,
012759,52428,26214, 0,
012860,52428,13107,65535,
012961,52428,13107,52428,
013062,52428,13107,39321,
013163,52428,13107,26214,
013264,52428,13107,13107,
013365,52428,13107, 0,
013466,52428, 0,65535,
013567,52428, 0,52428,
013668,52428, 0,39321,
013769,52428, 0,26214,
013870,52428, 0,13107,
013971,52428, 0, 0,
014072,39321,65535,65535,
014173,39321,65535,52428,
014274,39321,65535,39321,
014375,39321,65535,26214,
014476,39321,65535,13107,
014577,39321,65535, 0,
014678,39321,52428,65535,
014779,39321,52428,52428,
014880,39321,52428,39321,
014981,39321,52428,26214,
015082,39321,52428,13107,
015183,39321,52428, 0,
015284,39321,39321,65535,
015385,39321,39321,52428,
015486,39321,39321,39321,
015587,39321,39321,26214,
015688,39321,39321,13107,
015789,39321,39321, 0,
015890,39321,26214,65535,
015991,39321,26214,52428,
016092,39321,26214,39321,
016193,39321,26214,26214,
016294,39321,26214,13107,
016395,39321,26214, 0,
016496,39321,13107,65535,
016597,39321,13107,52428,
016698,39321,13107,39321,
016799,39321,13107,26214,
0168100,39321,13107,13107,
0169101,39321,13107, 0,
0170102,39321, 0,65535,
0171103,39321, 0,52428,
0172104,39321, 0,39321,
0173105,39321, 0,26214,
0174106,39321, 0,13107,
0175107,39321, 0, 0,
0176108,26214,65535,65535,
0177109,26214,65535,52428,
0178110,26214,65535,39321,
0179111,26214,65535,26214,
0180112,26214,65535,13107,
0181113,26214,65535, 0,
0182114,26214,52428,65535,
0183115,26214,52428,52428,
0184116,26214,52428,39321,
0185117,26214,52428,26214,
0186118,26214,52428,13107,
0187119,26214,52428, 0,
0188120,26214,39321,65535,
0189121,26214,39321,52428,
0190122,26214,39321,39321,
0191123,26214,39321,26214,
0192124,26214,39321,13107,
0193125,26214,39321, 0,
0194126,26214,26214,65535,
0195127,26214,26214,52428,
0196128,26214,26214,39321,
0197129,26214,26214,26214,
0198130,26214,26214,13107,
0199131,26214,26214, 0,
0200132,26214,13107,65535,
0201133,26214,13107,52428,
0202134,26214,13107,39321,
0203135,26214,13107,26214,
0204136,26214,13107,13107,
0205137,26214,13107, 0,
0206138,26214, 0,65535,
0207139,26214, 0,52428,
0208140,26214, 0,39321,
0209141,26214, 0,26214,
0210142,26214, 0,13107,
0211143,26214, 0, 0,
0212144,13107,65535,65535,
0213145,13107,65535,52428,
0214146,13107,65535,39321,
0215147,13107,65535,26214,
0216148,13107,65535,13107,
0217149,13107,65535, 0,
0218150,13107,52428,65535,
0219151,13107,52428,52428,
0220152,13107,52428,39321,
0221153,13107,52428,26214,
0222154,13107,52428,13107,
0223155,13107,52428, 0,
0224156,13107,39321,65535,
0225157,13107,39321,52428,
0226158,13107,39321,39321,
0227159,13107,39321,26214,
0228160,13107,39321,13107,
0229161,13107,39321, 0,
0230162,13107,26214,65535,
0231163,13107,26214,52428,
0232164,13107,26214,39321,
0233165,13107,26214,26214,
0234166,13107,26214,13107,
0235167,13107,26214, 0,
0236168,13107,13107,65535,
0237169,13107,13107,52428,
0238170,13107,13107,39321,
0239171,13107,13107,26214,
0240172,13107,13107,13107,
0241173,13107,13107, 0,
0242174,13107, 0,65535,
0243175,13107, 0,52428,
0244176,13107, 0,39321,
0245177,13107, 0,26214,
0246178,13107, 0,13107,
0247179,13107, 0, 0,
0248180, 0,65535,65535,
0249181, 0,65535,52428,
0250182, 0,65535,39321,
0251183, 0,65535,26214,
0252184, 0,65535,13107,
0253185, 0,65535, 0,
0254186, 0,52428,65535,
0255187, 0,52428,52428,
0256188, 0,52428,39321,
0257189, 0,52428,26214,
0258190, 0,52428,13107,
0259191, 0,52428, 0,
0260192, 0,39321,65535,
0261193, 0,39321,52428,
0262194, 0,39321,39321,
0263195, 0,39321,26214,
0264196, 0,39321,13107,
0265197, 0,39321, 0,
0266198, 0,26214,65535,
0267199, 0,26214,52428,
0268200, 0,26214,39321,
0269201, 0,26214,26214,
0270202, 0,26214,13107,
0271203, 0,26214, 0,
0272204, 0,13107,65535,
0273205, 0,13107,52428,
0274206, 0,13107,39321,
0275207, 0,13107,26214,
0276208, 0,13107,13107,
0277209, 0,13107, 0,
0278210, 0, 0,65535,
0279211, 0, 0,52428,
0280212, 0, 0,39321,
0281213, 0, 0,26214,
0282214, 0, 0,13107,
0283215,61166, 0, 0,
0284216,56797, 0, 0,
0285217,48059, 0, 0,
0286218,43690, 0, 0,
0287219,34952, 0, 0,
0288220,30583, 0, 0,
0289221,21845, 0, 0,
0290222,17476, 0, 0,
0291223, 8738, 0, 0,
0292224, 4369, 0, 0,
0293225, 0,61166, 0,
0294226, 0,56797, 0,
0295227, 0,48059, 0,
0296228, 0,43690, 0,
0297229, 0,34952, 0,
0298230, 0,30583, 0,
0299231, 0,21845, 0,
0300232, 0,17476, 0,
0301233, 0, 8738, 0,
0302234, 0, 4369, 0,
0303235, 0, 0,61166,
0304236, 0, 0,56797,
0305237, 0, 0,48059,
0306238, 0, 0,43690,
0307239, 0, 0,34952,
0308240, 0, 0,30583,
0309241, 0, 0,21845,
0310242, 0, 0,17476,
0311243, 0, 0, 8738,
0312244, 0, 0, 4369,
0313245,61166,61166,61166,
0314246,56797,56797,56797,
0315247,48059,48059,48059,
0316248,43690,43690,43690,
0317249,34952,34952,34952,
0318250,30583,30583,30583,
0319251,21845,21845,21845,
0320252,17476,17476,17476,
0321253, 8738, 8738, 8738,
0322254, 4369, 4369, 4369,
0323255, 0, 0, 0};
0324/****************** for MakeView1 *******************/
0325/**************** basic draw information ***********/
0326/* unsigned char* pD; // bitmap buffer */
0327PixMap* pD1=NULL;
0328/* int depthD; // Mac standard 256 colors */
0329/* int widthD; // picture size */
0330/* int heightD; */
0331/* int coloD; // current color for drawing */
0332unsigned char rD1,gD1,bD1;
0333/* int xD; // current pen position */
0334/* int yD; */
0335/* int cliplD; // clip rect left */
0336/* int cliprD; */
0337/* int cliptD; */
0338/* int clipbD; */
0339PixMap* pD2=NULL;
0340PixMap* pD3=NULL; /* for thumbnail */
0341/************** saving gif in directory pc ********************/
0342int saveG=0;
0343char saveGfn[30];
0344FILE *gfp;
0345/************************** for base64 encode ********************************/
0346int k64=0,l64=0;
0347unsigned char in64[4],out64[5];
0348char b64digits[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
0349
0350int MakeView(int width,int height)
0351{
0352 int i,j;
0353 widthD=width;
0354 heightD=height;
0355 pD=(unsigned char *)malloc((widthD+1)*heightD*sizeof(char));
0356 j=widthD*heightD;
0357 for(i=0;i<j;i++) pD[i]=0;
0358 depthD=8;
0359 if(widthD%8==0) polyWidthD=widthD/8; // width for buffer
0360 else polyWidthD=width/8+1;
0361 poD=(unsigned char *)malloc(polyWidthD*heightD*sizeof(char));
0362 cliplD=0; // clip rect left
0363 cliprD=widthD;
0364 cliptD=0;
0365 clipbD=heightD;
0366 polyD=0; // not polygon mode initially
0367 widMin=0;
0368 widMax=widthD;
0369 heiMin=0;
0370 heiMax=heightD;
0371}
0372
0373int SetColor(int r1,int g1,int b1)
0374{
0375 int i;
0376 int r,g,b;
0377
0378 r=r1*(0xffff/100);
0379 g=g1*(0xffff/100);
0380 b=b1*(0xffff/100);
0381 return SetColor1(r,g,b);
0382}
0383
0384int SetColor1(int r,int g,int b)
0385{
0386 int i;
0387 if(r==0&&g==0&&b==0){
0388 coloD=255;
0389 return;
0390 }
0391 if(r==0xffff&&g==0xffff&&b==0xffff){
0392 coloD=0;
0393 return;
0394 }
0395 if(r==0&&g==0){
0396 i=(b+2185)/4369;
0397 if(i%3!=0){
0398 coloD=245-(i-i/3);
0399 return;
0400 }
0401 }
0402 if(g==0&&b==0){
0403 i=(r+2185)/4369;
0404 if(i%3!=0){
0405 coloD=225-(i-i/3);
0406 return;
0407 }
0408 }
0409 if(b==0&&r==0){
0410 i=(g+2185)/4369;
0411 if(i%3!=0){
0412 coloD=235-(i-i/3);
0413 return;
0414 }
0415 }
0416 if(b==g&&r==g){ // gray scale
0417 i=(g+2185)/4369;
0418 if(i!=0&&i%3!=0){
0419 coloD=255-(i-i/3);
0420 return;
0421 }
0422 }
0423 coloD=215-((r+6554)/13107)*36-((g+6554)/13107)*6-(b+6554)/13107;
0424 if(coloD==215) coloD=255;
0425}
0426
0427int MoveTo(int x,int y)
0428{
0429 if(polyD){
0430 firstPtxD=x;
0431 firstPtyD=y;
0432 if(x<pxminD) pxminD=x;
0433 if(x>pxmaxD) pxmaxD=x;
0434 if(y<pyminD) pyminD=y;
0435 if(y>pymaxD) pymaxD=y;
0436 }
0437 xD=x;
0438 yD=y;
0439}
0440
0441int LineTo(int x1,int y1)
0442{
0443 int a,dx,dy,b,two_a,two_b,xcrit,eps;
0444 unsigned char i;
0445 if(polyD){
0446 if(x1<pxminD) pxminD=x1;
0447 if(x1>pxmaxD) pxmaxD=x1;
0448 if(y1<pyminD) pyminD=y1;
0449 if(y1>pymaxD) pymaxD=y1;
0450 if(xD*x1<0){
0451 if((xD*y1-yD*x1)/(xD-x1)<0) vertXD++;
0452 }
0453 if(yD*y1<0){
0454 if((yD*x1-xD*y1)/(yD-y1)<0) horiXD++;
0455 }
0456 }
0457 dx=1;
0458 a=x1-xD;
0459 if(a<0){
0460 dx=-1;
0461 a=-a;
0462 }
0463
0464 dy=1;
0465 b=y1-yD;
0466 if(b<0){
0467 dy=-1;
0468 b=-b;
0469 }
0470 two_a = 2*a;
0471 two_b = 2*b;
0472 xcrit = -b+two_a;
0473 eps=0;
0474
0475 for(;;){
0476 if(cliplD<=xD && xD<cliprD && cliptD<=yD && yD<clipbD){
0477 if(polyD){
0478 i=1<<(xD%8);
0479 poD[yD*polyWidthD+xD/8]|=i;
0480 }
0481 else *(pD+yD*widthD+xD)=coloD;
0482 }
0483 if(xD==x1&&yD==y1) break;
0484 if(eps<=xcrit) xD += dx, eps+=two_b;
0485 if(eps>=a || a<=b) yD += dy, eps-=two_a;
0486 }
0487}
0488
0489void drawGrid()
0490{
0491 int i;
0492 SetColor(100,70,60);
0493 for(i=0;i<heightD;i+=10){
0494 MoveTo(0,i);
0495 LineTo(widthD,i);
0496 }
0497 for(i=0;i<widthD;i+=10){
0498 MoveTo(i,0);
0499 LineTo(i,heightD);
0500 }
0501 SetColor(80,40,20);
0502 for(i=0;i<heightD;i+=50){
0503 MoveTo(0,i);
0504 LineTo(widthD,i);
0505 }
0506 for(i=0;i<widthD;i+=50){
0507 MoveTo(i,0);
0508 LineTo(i,heightD);
0509 }
0510 SetColor(40,20,10);
0511 for(i=0;i<heightD;i+=100){
0512 MoveTo(0,i);
0513 LineTo(widthD,i);
0514 }
0515 for(i=0;i<widthD;i+=100){
0516 MoveTo(i,0);
0517 LineTo(i,heightD);
0518 }
0519}
0520
0521int OpenPoly()
0522{
0523 int i,j;
0524 for(j=0;j<heightD;j++)
0525 for(i=0;i<polyWidthD;i++) poD[j*polyWidthD+i]=0;
0526 polyD=1; // polygon mode on
0527 vertXD=0; // left-upper line crossings
0528 horiXD=0;
0529 pxminD=10000;
0530 pxmaxD=-10000;
0531 pyminD=10000;
0532 pymaxD=-10000;
0533}
0534
0535int ClosePoly()
0536{
0537/* [item][island][line]
0538 item 0 first column
0539 item 1 last column
0540 item 2 first upper continuous island (if -1 no upper island)
0541 item 3 second upper continuous island
0542 item 4 first lower continuous island (if -1 no lower island)
0543 item 5 second lower continuous island
0544 item 6 degenerative island (if 1)
0545 item 7 left corner (if 1)
0546 item 8 right corner (if 1)
0547*/
0548 int isl[3]; // number od islands
0549 int transitD[9][10][3]; // first black points and last black points
0550 // for three lines
0551 int cornerBlack;
0552 int i,j,k,l,n,i1,i2,i3,i4,i5,i6,i7,i8;
0553 int topin; // top is inside
0554 unsigned char m;
0555
0556 LineTo(firstPtxD,firstPtyD); // close polygon
0557 polyD=0; // polygon mode off
0558 if(pxminD>=widthD) return; // out of view
0559 if(pxmaxD<0) return;
0560 if(pyminD>=heightD) return;
0561 if(pymaxD<0) return;
0562
0563 pxmaxD++; // past-the-boundary value
0564 pymaxD++;
0565
0566 if(pxminD<0) pxminD=0; // crossing rect
0567 if(pxmaxD>widthD) pxmaxD=widthD;
0568 if(pyminD<0) pyminD=0;
0569 if(pymaxD>heightD) pymaxD=heightD;
0570
0571 if(pxminD==(pxmaxD-1)) return;
0572 if(pyminD==(pymaxD-1)) return;
0573
0574 if(pyminD>0) topin=1; // top is in the view
0575 else topin=0;
0576
0577 cornerBlack=0; // upper left corner is white
0578 if(pxminD==0&&pyminD==0){
0579 if(vertXD%2==1) cornerBlack=1;
0580 }
0581
0582 for(j=pyminD;j<pymaxD;j++){
0583 for(k=0;k<10;k++)
0584 for(n=0;n<9;n++){
0585 transitD[n][k][0]=transitD[n][k][1];
0586 transitD[n][k][1]=transitD[n][k][2];
0587 transitD[n][k][2]=-1;
0588 }
0589 isl[0]=isl[1];
0590 isl[1]=isl[2];
0591 k=0; // point white
0592 isl[2]=0;
0593 for(i=pxminD;i<pxmaxD;i++){
0594 m=poD[j*polyWidthD+i/8];
0595 if(m&(1<<(i%8))){ // black
0596 if(k==0){
0597 transitD[0][isl[2]][2]=i; // first black
0598 k=1;
0599 if(i==pxminD) transitD[7][isl[2]][2]=1;
0600 if(i==pxmaxD-1) transitD[8][isl[2]][2]=1;
0601 }
0602 }
0603 else{ // white
0604 if(k==1){
0605 transitD[1][isl[2]][2]=i-1; // last black
0606 k=0;
0607 isl[2]++;
0608 }
0609 }
0610 } /* for(i=pxminD;i<pxmaxD;i++) */
0611 if(k==1){
0612 transitD[1][isl[2]][2]=i-1; // last point is black
0613 transitD[8][isl[2]][2]=1;
0614 isl[2]++;
0615 }
0616 if(j>pyminD){ // if line 1 and above , process line 0
0617 for(k=0;k<isl[1];k++){
0618 i1=transitD[0][k][1];
0619 i2=transitD[1][k][1];
0620 i3=0;
0621 for(i4=0;i4<isl[2];i4++){
0622 i5=transitD[0][i4][2];
0623 i6=transitD[1][i4][2];
0624 if(i6>=(i1-1)&&i5<=(i2+1)){
0625 if(i3<2) transitD[4+i3][k][1]=i4; // lower
0626 i3++;
0627 }
0628 }
0629 } /* for(k=0;k<isl[1];k++){ */
0630 for(k=0;k<isl[2];k++){
0631 i1=transitD[0][k][2];
0632 i2=transitD[1][k][2];
0633 i3=0;
0634 for(i4=0;i4<isl[1];i4++){
0635 i5=transitD[0][i4][1];
0636 i6=transitD[1][i4][1];
0637 if(i6>=(i1-1)&&i5<=(i2+1)){
0638 if(i3<2) transitD[2+i3][k][2]=i4; // upper
0639 i3++;
0640 }
0641 }
0642 } /* for(k=0;k<isl[2];k++){ */
0643 if(j==pyminD+1){ // for the second line
0644 if(topin){
0645 for(k=0;k<isl[1];k++){
0646 if(transitD[5][k][1]!=-1) transitD[6][k][1]=1; // two lowers - degenerative
0647 else if(transitD[8][k][1]!=1){ // one lower and not right corner
0648 transitD[6][k][1]=1; // one lower - consecutive degenerative
0649 if(transitD[4][k][1]!=-1) transitD[6][ transitD[4][k][1] ][2]=1; // make the lower degenerative
0650 }
0651 }
0652 for(k=0;k<isl[2];k++){
0653 if(transitD[2][k][2]==-1){
0654 if(transitD[8][k][2]!=1) transitD[6][k][2]=1; // no uppers and not right edge
0655 }
0656 }
0657 } /* if(topin){ */
0658 } /* if(j==pyminD+1){ */
0659 } /* if(j>pyminD) */
0660 if(j>pyminD+1){ // re-evaluate 3-line data and fill first line
0661 for(k=0;k<isl[2];k++){
0662 if(transitD[2][k][2]==-1){
0663 if(transitD[8][k][2]!=1) transitD[6][k][2]=1; // no uppers and not right edge
0664 }
0665 else if(transitD[3][k][2]==-1&&transitD[6][ transitD[2][k][2] ][1]==1){ // one upper and it's degenerative
0666 if(transitD[5][ transitD[2][k][2] ][1]==-1) transitD[6][k][2]=1; // the upper has one lower
0667 }
0668 }
0669 for(k=0;k<isl[2];k++){
0670 if(transitD[3][k][2]!=-1) transitD[6][k][2]=1; // second-upper exists. join
0671 }
0672 for(k=0;k<isl[1];k++){
0673 if(transitD[5][k][1]!=-1){ // second-lower exists. cancel lowers' degene
0674 transitD[6][ transitD[4][k][1] ][2]=-1;
0675 transitD[6][ transitD[5][k][1] ][2]=-1;
0676 }
0677 }
0678 i8=cornerBlack; // starting color
0679 i7=pxminD;
0680 for(k=0;k<isl[0];k++){
0681 i1=transitD[0][k][0];
0682 if(i8){ // if black, paint from i7 to i1
0683 for(l=i7;l<i1;l++)
0684 poD[(j-2)*polyWidthD+l/8]|=(1<<l%8);
0685 }
0686 if(transitD[6][k][0]!=1){
0687 if(i8==1) i8=0;
0688 else i8=1;
0689 }
0690 i7=transitD[1][k][0]+1;
0691 }
0692 if(i8==1&&i7<pxmaxD){ // paint to the end of line
0693 for(l=i7;l<pxmaxD;l++)
0694 poD[(j-2)*polyWidthD+l/8]|=(1<<l%8);
0695 }
0696 } /* if(j>pymind+1) */
0697 } /* for(j=pyminD;j<pymaxD,j++) */
0698/* now do for last two lines */
0699 for(j=1;j<3;j++){
0700 i8=cornerBlack;
0701 i7=pxminD;
0702 for(k=0;k<isl[j];k++){
0703 i1=transitD[0][k][j];
0704 if(i8){ // if black, paint from i7 to i1
0705 for(l=i7;l<i1;l++)
0706 poD[(pymaxD-3+j)*polyWidthD+l/8]|=(1<<l%8);
0707 }
0708 if(transitD[6][k][j]!=1){
0709 if(i8==1) i8=0;
0710 else i8=1;
0711 }
0712 i7=transitD[1][k][j]+1;
0713 }
0714 if(i8==1&&i7<pxmaxD){ // paint to the end of line
0715 for(l=i7;l<pxmaxD;l++)
0716 poD[(pymaxD-3+j)*polyWidthD+l/8]|=(1<<l%8);
0717 }
0718 }
0719/* now poD has been painted, next we will paint pD in coloD */
0720 for(j=pyminD;j<pymaxD;j++){
0721 for(i=pxminD;i<pxmaxD;i++){
0722 m=poD[j*polyWidthD+i/8];
0723 if(m&(1<<(i%8)))
0724 *(pD+j*widthD+i)=coloD;
0725 }
0726 }
0727}
0728
0729int FontInfo(int font,int direc,int mode)
0730{
0731 fontD=font;
0732 switch(font){
0733 case 11: // 6x11
0734 pfD=fontdata_6x11;
0735 ascentD=8;
0736 descentD=3;
0737 fontWidthD=6;
0738 fontHeightD=11;
0739 widthBytesD=1;
0740 fontBytesD=11;
0741 break;
0742 case 16: // 8x16
0743 pfD=fontdata_8x16;
0744 ascentD=11;
0745 descentD=5;
0746 fontWidthD=8;
0747 fontHeightD=16;
0748 widthBytesD=1;
0749 fontBytesD=16;
0750 break;
0751 case 22: // 12x22
0752 pfD=fontdata_12x22;
0753 ascentD=16;
0754 descentD=6;
0755 fontWidthD=12;
0756 fontHeightD=22;
0757 widthBytesD=2;
0758 fontBytesD=44;
0759 break;
0760 }
0761 direcD=direc;
0762 modeD=mode;
0763}
0764
0765int DrawString(char *c)
0766{
0767 long int dots[1056]; // up to and including double size of 12x22
0768 int h,i,j,k,l,m,n,k0,x,y;
0769 unsigned char test,mask;
0770
0771 if(modeD==0);
0772 else{
0773 i=strlen(c);
0774 i=i*fontWidthD;
0775 if(modeD==2) i/=2; /* center */
0776 if(direcD==0) xD-=i;
0777 else yD+=i;
0778 }
0779 for(h=0;c[h]!='\0';h++){
0780 k0=fontBytesD*(int)c[h];
0781 n=0;
0782 for(i=0;i<fontHeightD;i++){
0783 k=k0+i*widthBytesD;
0784 m=0;
0785 for(j=0;j<widthBytesD;j++){
0786 test=pfD[k+j];
0787 mask=0x80;
0788 for(l=0;l<8;l++){
0789 if(test&mask){
0790 if(direcD==0){ // horizontal
0791 y=yD-ascentD+i;
0792 x=xD+j*8+l;
0793 }
0794 else{ // vertical
0795 x=xD-ascentD+i;
0796 y=yD-j*8-l;
0797 }
0798 if(x>=0&&x<widthD&&y>=0&&y<heightD)
0799 dots[n++]=y*widthD+x;
0800 }
0801 mask>>=1;
0802 m++;
0803 if(m==fontWidthD) break;
0804 }
0805 }
0806 } /* for(i=0;i<fontHeightD;i++) */
0807 for(j=0;j<n;j++) *(pD+dots[j])=coloD;
0808 if(direcD==0) xD+=fontWidthD;
0809 else yD-=fontWidthD;
0810 } /* for(h=0;c[h]!='\0';h++) */
0811}
0812
0813int DrawNum(int i)
0814{
0815 char c[15];
0816 sprintf(c,"%i",i);
0817 DrawString(c);
0818}
0819
0820int DrawFNum(char *f,double a)
0821{
0822 char c[30];
0823 sprintf(c,f,a);
0824 DrawString(c);
0825}
0826
0827int MakeGraph(int left,int top,int right,int bottom)
0828{
0829 lgD=left;
0830 tgD=top;
0831 rgD=right;
0832 bgD=bottom;
0833 htD=0;
0834 hlD=0;
0835 vlD=0;
0836}
0837
0838int HorizTime()
0839{
0840 htD=1;
0841}
0842
0843int HorizLog()
0844{
0845 hlD=1;
0846}
0847
0848int VertLog()
0849{
0850 vlD=1;
0851}
0852
0853int format(int col,double num,char* fig)
0854{
0855 int i,j,colst,inte1,ncha;
0856 double a,frac;
0857 double inte;
0858 char c[10]={'0','1','2','3','4','5','6','7','8','9'};
0859
0860 ncha=0;
0861 i=0;
0862 if(num<0.){
0863 i++;
0864 fig[ncha++]='-';
0865 num=fabs(num);
0866 }
0867
0868 if(num!=0.){
0869 a=log10(num);
0870 frac=modf(a,&inte);
0871 colst=inte+0.1;
0872 if(colst<0) colst=0;
0873 }
0874 else colst=0;
0875
0876 num+=pow(10,colst-6);
0877
0878 frac=num/pow(10,colst);
0879 if(frac<1.&&frac>0.9999) frac=1.;
0880 for(j=colst;j>=0;j--){
0881 if(frac<1.&&frac>0.9999) frac=1.;
0882 frac=modf(frac,&inte)*10.;
0883 inte1=inte;
0884 i++;
0885 fig[ncha++]=c[inte1];
0886 }
0887
0888 if(col!=0){
0889 i++;
0890 fig[ncha++]='.';
0891 for(j=col;j>0;j--){
0892 if(frac<1.&&frac>0.9999) frac=1.;
0893 frac=modf(frac,&inte)*10.;
0894 inte1=inte;
0895 i++;
0896 fig[ncha++]=c[inte1];
0897 }
0898 }
0899 fig[ncha]='\0';
0900 return i;
0901}
0902
0903
0904int HorizScale(char *c,double left,double right)
0905{
0906 int i,j,ix,colx;
0907 double stepc,stepf,delta,intef,frac,num;
0908 char ar[12];
0909 double mdy,hms,scl;
0910 char *month[]={"Jan","Feb","Mar","Apr","May","Jun",
0911 "Jul","Aug","Sep","Oct","Nov","Dec"};
0912
0913 ldgD=left;
0914 rdgD=right;
0915 delta=right-left;
0916 MoveTo(lgD,bgD);
0917 LineTo(rgD,bgD);
0918if(htD==0){
0919 frac=modf(log10(delta),&intef);
0920 stepc=pow(10.,intef-1);
0921 stepf=stepc;
0922 if(frac<0.2) stepf*=0.5;
0923 else if(frac<0.8) stepc*=5.;
0924 else{
0925 stepc*=10.;
0926 stepf*=5.;
0927 }
0928 frac=modf(log10(stepc),&intef);
0929// if(log10(stepc)<0.) colx=-intef+1.;
0930 if(log10(stepc)<0.) colx=-log10(stepc)+0.8;
0931 else colx=0;
0932 frac=modf(left/stepc,&intef);
0933 frac=intef;
0934 if(hlD){
0935 stepc=1.;
0936 colx=0;
0937 }
0938 while(1){
0939 num=frac*stepc; // x value for grid
0940 if(num>rdgD) break;
0941 ix=(rgD-lgD)*((num-ldgD)/(rdgD-ldgD))+lgD;
0942 i=format(colx,num,ar);
0943 MoveTo(ix,tgD);
0944 LineTo(ix,bgD+2);
0945 FontInfo(11,0,0);
0946 for(i=0;ar[i]!='\0';i++);
0947 if(hlD){
0948 MoveTo(ix-i*3+4,bgD+12);
0949 DrawString(ar);
0950 MoveTo(ix-i*3-6,bgD+20);
0951 DrawString("10");
0952 }
0953 else{
0954 MoveTo(ix-i*3,bgD+12);
0955 DrawString(ar);
0956 }
0957 frac++;
0958 }
0959}
0960else{ /* horiz is time */
0961 mdy=mdyday(left);
0962 hms=hmsday(left);
0963 scl=(rgD-lgD)/delta; /* dots per day */
0964 if(delta>700.){ /* yr */
0965 frac=fmod(mdy*1000000.,10000.);
0966 while(1){
0967 num=refday(1.01+frac/1000000.,0.); // x value for grid
0968 if(num>rdgD) break;
0969 ix=scl*(num-ldgD)+lgD;
0970 i=format(0,frac,ar);
0971 MoveTo(ix,tgD);
0972 LineTo(ix,bgD+2);
0973 if(num+182.>rdgD) break;
0974 FontInfo(11,0,2); /* center */
0975 ix=scl*(num+182.-ldgD)+lgD;
0976 MoveTo(ix,bgD+12);
0977 if(scl>0.07) DrawString(ar);
0978 else DrawString(&ar[2]);
0979 frac++; /* add a year */
0980 }
0981 }
0982 else if(delta>70.){ /* mo */
0983 stepc=fmod(mdy*1000000.,10000.);
0984 stepf=floor(mdy);
0985 while(1){
0986 num=refday(stepf+0.01+stepc/1000000.,0.); // x value for grid
0987 if(num>rdgD) break;
0988 if(num>ldgD){
0989 ix=scl*(num-ldgD)+lgD;
0990 MoveTo(ix,tgD);
0991 LineTo(ix,bgD+2);
0992 }
0993 if(num+15.>rdgD) break;
0994 FontInfo(11,0,2); /* center */
0995 ix=scl*(num+15.-ldgD)+lgD;
0996 MoveTo(ix,bgD+12);
0997 i=stepf;
0998 DrawString(month[i-1]);
0999 stepf++;
1000 if(stepf>12.1){
1001 stepf=1.;
1002 stepc++;
1003 }
1004 }
1005 }
1006 else if(delta>2.){ /* day */
1007 num=refday(mdy,0.);
1008 while(1){
1009 if(num>rdgD) break;
1010 stepf=mdyday(num);
1011 stepc=floor(stepf*100.);
1012 stepf=fmod(stepc,100.);
1013 i=1;
1014 if(scl<12.){
1015 if(fmod(num+0.001,7.)>1.) i=0;
1016 }
1017 if(num>ldgD){
1018 ix=scl*(num-ldgD)+lgD;
1019 MoveTo(ix,tgD);
1020 LineTo(ix,bgD+2*i);
1021 }
1022 if(i==1){
1023 if(num+0.5>rdgD) break;
1024 FontInfo(11,0,2); /* center */
1025 ix=scl*(num+0.5-ldgD)+lgD;
1026 MoveTo(ix,bgD+12);
1027 format(0,stepf,ar);
1028 DrawString(ar);
1029 }
1030 num++;
1031 }
1032 }
1033 else{ /* hour */
1034 stepc=floor(hms);
1035 num=refday(mdy,stepc);
1036 while(1){
1037 if(num>rdgD) break;
1038 if(num>ldgD){
1039 ix=scl*(num-ldgD)+lgD;
1040 MoveTo(ix,tgD);
1041 LineTo(ix,bgD+2);
1042 }
1043 if(num>rdgD) break;
1044 FontInfo(11,0,2); /* center */
1045 ix=scl*(num-ldgD)+lgD;
1046 MoveTo(ix,bgD+12);
1047 i=format(0,stepc,ar);
1048 DrawString(ar);
1049 stepc++;
1050 if(stepc>23.5) stepc=0;
1051 num+=0.041666666;
1052 }
1053 }
1054 }
1055 for(i=0;c[i]!='\0';i++);
1056 if(hlD) MoveTo((lgD+rgD-i*8)/2,bgD+33);
1057 else MoveTo((lgD+rgD-i*8)/2,bgD+22);
1058 FontInfo(16,0,0);
1059 DrawString(c);
1060}
1061
1062int VertScale(char *c,double bottom,double top)
1063{
1064 int i,j,iy,coly;
1065 double stepc,stepf,delta,intef,frac,num;
1066 char ar[12];
1067
1068 bdgD=bottom;
1069 tdgD=top;
1070 delta=top-bottom;
1071 frac=modf(log10(delta),&intef);
1072 stepc=pow(10.,intef-1);
1073 stepf=stepc;
1074 if(frac<0.2) stepf*=0.5;
1075 else if(frac<0.8) stepc*=5.;
1076 else{
1077 stepc*=10.;
1078 stepf*=5.;
1079 }
1080 MoveTo(lgD,tgD);
1081 LineTo(lgD,bgD);
1082
1083 frac=modf(log10(stepc),&intef);
1084// if(log10(stepc)<0.) coly=-intef+1.;
1085 if(log10(stepc)<0.) coly=-log10(stepc)+0.8;
1086 else coly=0;
1087 frac=modf(bottom/stepc,&intef);
1088 frac=intef;
1089 if(vlD){
1090 stepc=1.;
1091 coly=0;
1092 }
1093 j=0;
1094 while(1){
1095 num=frac*stepc; // y value for grid
1096 if(num>tdgD) break;
1097 iy=(tgD-bgD)*((num-bdgD)/(tdgD-bdgD))+bgD;
1098 i=format(coly,num,ar);
1099 if(i>j) j=i;
1100 MoveTo(lgD-2,iy);
1101 LineTo(rgD,iy);
1102 FontInfo(11,0,0);
1103 for(i=0;ar[i]!='\0';i++);
1104 if(vlD){
1105 MoveTo(lgD-i*6-3,iy-1);
1106 DrawString(ar);
1107 MoveTo(lgD-i*6-12,iy+6);
1108 DrawString("10");
1109 }
1110 else{
1111 MoveTo(lgD-i*6-3,iy+3);
1112 DrawString(ar);
1113 }
1114 frac++;
1115 }
1116 for(i=0;c[i]!='\0';i++);
1117 if(vlD) MoveTo(lgD-j*6-16,(bgD+tgD+i*8)/2);
1118 else MoveTo(lgD-j*6-8,(bgD+tgD+i*8)/2);
1119 FontInfo(16,1,0);
1120 DrawString(c);
1121}
1122
1123int MoveToG(double x,double y)
1124{
1125 int savel,saver,savet,saveb;
1126 int ix,iy;
1127
1128 savel=cliplD;
1129 saver=cliprD;
1130 savet=cliptD;
1131 saveb=clipbD;
1132 cliplD=lgD;
1133 cliprD=rgD;
1134 cliptD=tgD;
1135 clipbD=bgD;
1136
1137 ix=(rgD-lgD)*((x-ldgD)/(rdgD-ldgD))+lgD;
1138 iy=(tgD-bgD)*((y-bdgD)/(tdgD-bdgD))+bgD;
1139 MoveTo(ix,iy);
1140
1141 cliplD=savel;
1142 cliprD=saver;
1143 cliptD=savet;
1144 clipbD=saveb;
1145}
1146
1147int LineToG(double x,double y)
1148{
1149 int savel,saver,savet,saveb;
1150 int ix,iy;
1151
1152 savel=cliplD;
1153 saver=cliprD;
1154 savet=cliptD;
1155 saveb=clipbD;
1156 cliplD=lgD;
1157 cliprD=rgD;
1158 cliptD=tgD;
1159 clipbD=bgD;
1160
1161
1162 ix=(rgD-lgD)*((x-ldgD)/(rdgD-ldgD))+lgD;
1163 iy=(tgD-bgD)*((y-bdgD)/(tdgD-bdgD))+bgD;
1164 LineTo(ix,iy);
1165
1166 cliplD=savel;
1167 cliprD=saver;
1168 cliptD=savet;
1169 clipbD=saveb;
1170}
1171
1172int PlotG(int mark,double x,double y)
1173{
1174 int ix,iy;
1175
1176 ix=(rgD-lgD)*((x-ldgD)/(rdgD-ldgD))+lgD;
1177 iy=(tgD-bgD)*((x-bdgD)/(tdgD-bdgD))+bgD;
1178 MoveTo(ix-1,iy-1);
1179 LineTo(ix-1,iy+1);
1180 LineTo(ix+1,iy+1);
1181 LineTo(ix-1,iy+1);
1182 LineTo(ix,iy+1);
1183 LineTo(ix,iy);
1184}
1185
1186
1187int GifOutMin()
1188{
1189 int i,j,k;
1190 heiMin=10000;
1191 heiMax=-10000;
1192 widMin=10000;
1193 widMax=-10000;
1194 for(j=0;j<heightD;j++){
1195 for(i=0;i<widthD;i++){
1196 k=pD[widthD*j+i]; // CHARACTER
1197 if(k>0){
1198 if(i<widMin) widMin=i;
1199 if(i>widMax) widMax=i;
1200 if(j<heiMin) heiMin=j;
1201 if(j>heiMax) heiMax=j;
1202 }
1203 }
1204 }
1205 heiMax++;
1206 widMax++;
1207 i=GifOut();
1208 return i;
1209}
1210
1211int GifSaveMin(int n)
1212{
1213 int i,j,k;
1214 heiMin=10000;
1215 heiMax=-10000;
1216 widMin=10000;
1217 widMax=-10000;
1218 for(j=0;j<heightD;j++){
1219 for(i=0;i<widthD;i++){
1220 k=pD[widthD*j+i]; // CHARACTER
1221 if(k>0){
1222 if(i<widMin) widMin=i;
1223 if(i>widMax) widMax=i;
1224 if(j<heiMin) heiMin=j;
1225 if(j>heiMax) heiMax=j;
1226 }
1227 }
1228 }
1229 heiMax++;
1230 widMax++;
1231 GifSave(n);
1232 return 0;
1233}
1234
1235void outbyte1(int num,char *s)
1236{
1237 int i;
1238 unsigned char c;
1239 if(num<0){
1240 if(k64>0){
1241 out64[0]=b64digits[in64[0] >> 2];
1242 c=(in64[0] << 4) & 0x30;
1243 if (k64 > 1) c |= in64[1] >> 4;
1244 out64[1]=b64digits[c];
1245 out64[2] = (k64 < 2) ? '=' : b64digits[(in64[1] << 2) & 0x3c];
1246 out64[3] = '=';
1247 outbyte(4,out64);
1248 }
1249 }
1250 else{
1251 if(saveG==1||saveG==2) fwrite(s,sizeof(char),num,gfp);
1252 if(saveG==0||saveG==1) outbyte(num,s);
1253 if(saveG==3){
1254 for(i=0;i<num;i++){
1255 in64[k64]=s[i];
1256 k64++;
1257 if(k64==3){
1258 out64[0]=b64digits[in64[0] >> 2];
1259 out64[1]=b64digits[((in64[0] << 4) & 0x30) | (in64[1] >> 4)];
1260 out64[2]=b64digits[((in64[1] << 2) & 0x3c) | (in64[2] >> 6)];
1261 out64[3]=b64digits[in64[2] & 0x3f];
1262 outbyte(4,out64);
1263 k64=0;
1264 l64++;
1265 if(l64%18==0) outbyte(1,"\n");
1266 }
1267 }
1268 }
1269 }
1270
1271 return 0;
1272}
1273
1274int gifsize(int size)
1275{
1276 gsize=size;
1277 return 0;
1278}
1279
1280int GifOutMode(int mode)
1281{
1282 saveG=3;
1283 return 0;
1284}
1285
1286/**********************************************************************************
1287 GifOut
1288 saveG : 0 - out, 1 - out and save, 2 - save, 3 - base64
1289 pD1 : NULL - standard color table. pD[widthD*j+i];
1290 non-NULL - addaptive color table. (unsigned char)pD2->pixdata[widthD*j+i];
1291**********************************************************************************/
1292int GifOut()
1293{
1294 int i,j,k,l,o;
1295 unsigned char m;
1296 unsigned int step,red,green,blue;
1297
1298 int ctSize=256; /* may be overriden */
1299 int *prec;
1300 unsigned char *color;
1301 unsigned char pc[2000];
1302 int ipc,nn,n,nnstart,nstart;
1303 int bitsmin;
1304 int kstart;
1305 int clrcode;
1306 int wid,hei;
1307 int wid1,hei1;
1308 double ratio;
1309 int *nent;
1310 int r,g,b,r1,g1,b1;
1311
1312 if(pD1==NULL&&gsize!=1){ /* scaled output can be made only in the standard 256 colors */
1313 ratio=1./gsize;
1314 wid1=widMax-widMin;
1315 hei1=heiMax-heiMin;
1316 wid=wid1*ratio;
1317 hei=hei1*ratio;
1318 pD3=pcreate(4,wid,hei);
1319 k=wid*hei;
1320 nent=(int *)calloc(k,sizeof(int));
1321 for(j=0;j<hei1;j++){
1322 o=ratio*j;
1323 for(i=0;i<wid1;i++){
1324 l=ratio*i;
1325 k=pD[wid1*j+i];
1326 r=std256[k][1]/256;
1327 g=std256[k][2]/256;
1328 b=std256[k][3]/256;
1329 getpix(pD3,l,o,&r1,&g1,&b1);
1330 n=nent[o*wid+l];
1331 r=(r1*n+r)/(n+1);
1332 g=(g1*n+g)/(n+1);
1333 b=(b1*n+b)/(n+1);
1334 putpix(pD3,l,o,r,g,b);
1335 nent[o*wid+l]++;
1336 }
1337 }
1338 k=0;
1339 for(j=0;j<hei;j++){
1340 for(i=0;i<wid;i++){
1341 getpix(pD3,i,j,&r,&g,&b);
1342 pD[k++]=StdColorx(r*256,g*256,b*256);
1343 }
1344 }
1345 widMax=ratio*widMax;
1346 widMin=ratio*widMin;
1347 heiMax=ratio*heiMax;
1348 heiMin=ratio*heiMin;
1349 widthD=widMax-widMin;
1350 }
1351 wid=widMax-widMin;
1352 hei=heiMax-heiMin;
1353
1354 prec=(int *)malloc(4097*sizeof(int)); // code up to 12 bits
1355 color=(unsigned char*)malloc(4097*sizeof(unsigned char));
1356 for(i=0;i<4097;i++) prec[i]=-1;
1357
1358 outbyte1(6,"GIF89a");
1359 outbyte1(2,(char *)&wid);
1360 outbyte1(2,(char *)&hei);
1361
1362 if(pD1){
1363 switch(pD1->type){
1364 case 0:
1365 sizeOfCTD=0;
1366 ctSize=2;
1367 break;
1368 case 6:
1369 sizeOfCTD=1;
1370 ctSize=4;
1371 break;
1372 case 1:
1373 case 7:
1374 sizeOfCTD=3;
1375 ctSize=16;
1376 break;
1377 case 9:
1378 case 4:
1379 sizeOfCTD=7;
1380 ctSize=256;
1381 break;
1382 }
1383 }
1384 else sizeOfCTD=7;
1385 m=0xF0|sizeOfCTD;
1386 outbyte1(1,&m);
1387 m=0; // Background Color Index
1388 outbyte1(1,&m);
1389 m=0; // Pixel Aspect Ratio
1390 outbyte1(1,&m);
1391 if(pD1){
1392 if(pD1->type==4){
1393 pD2=pcreate(8,pD1->wid,pD1->hei); /* 8-bit non-standard index */
1394 cnvtype(pD1,pD2,2); /* reduce sparse */
1395 // cnvtype(pD1,pD2,0); /* reduce dark */
1396 outbyte1(768,pD2->data);
1397 }
1398 else outbyte1(pD1->idxlen,pD1->data);
1399 }
1400 else{
1401 step=0xFFFF/5;
1402 for(i=5;i>=0;i--){
1403 red=i*step;
1404 for(j=5;j>=0;j--){
1405 green=j*step;
1406 for(k=5;k>=0;k--){
1407 blue=k*step;
1408 if(i!=0||j!=0||k!=0){
1409 outbyte1(1,(char *)&red);
1410 outbyte1(1,(char *)&green);
1411 outbyte1(1,(char *)&blue);
1412 }
1413 }
1414 }
1415 }
1416 step=0xFFFF/15;
1417 green=0;
1418 blue=0;
1419 for(i=14;i>0;i--){
1420 if(i%3!=0){
1421 red=i*step;
1422 outbyte1(1,(char *)&red);
1423 outbyte1(1,(char *)&green);
1424 outbyte1(1,(char *)&blue);
1425 }
1426 }
1427 red=0;
1428 blue=0;
1429 for(i=14;i>0;i--){
1430 if(i%3!=0){
1431 green=i*step;
1432 outbyte1(1,(char *)&red);
1433 outbyte1(1,(char *)&green);
1434 outbyte1(1,(char *)&blue);
1435 }
1436 }
1437 red=0;
1438 green=0;
1439 for(i=14;i>0;i--){
1440 if(i%3!=0){
1441 blue=i*step;
1442 outbyte1(1,(char *)&red);
1443 outbyte1(1,(char *)&green);
1444 outbyte1(1,(char *)&blue);
1445 }
1446 }
1447 for(i=14;i>0;i--){
1448 if(i%3!=0){
1449 red=green=blue=i*step;
1450 outbyte1(1,(char *)&red);
1451 outbyte1(1,(char *)&green);
1452 outbyte1(1,(char *)&blue);
1453 }
1454 }
1455 red=0;
1456 green=0;
1457 blue=0;
1458 outbyte1(1,(char *)&red);
1459 outbyte1(1,(char *)&green);
1460 outbyte1(1,(char *)&blue);
1461 }
1462 m=0x2c; // image separator
1463 outbyte1(1,&m);
1464
1465 i=0; // image left position
1466 outbyte1(2,(char *)&i);
1467 i=0; // image top position
1468 outbyte1(2,(char *)&i);
1469 outbyte1(2,(char *)&wid);
1470 outbyte1(2,(char *)&hei);
1471 m=0x00|sizeOfCTD;
1472 outbyte1(1,&m);
1473
1474 m++; // LZW minimum code size 8
1475 if(m==1) m=2;
1476 outbyte1(1,&m);
1477 clrcode=1<<m; // clear code 0x100
1478 bitsD=m+1; // output number of bits
1479 bitsmin=bitsD; // initial number of bits
1480 for(i=0;i<ctSize;i++) color[i]=i; // the first 256 of 4097 colors
1481 for(i=0;i<260;i++) outBufD[i]=0;
1482 bitPtrD=0; // initialize output buffer
1483 emit(clrcode);
1484 ipc=0; // index for already-seen-color-sequence pc[]
1485 nnstart=0; // initial index value for nn used for pc[]
1486 nstart=clrcode+2; // n is index for preceeding code, prec
1487 for(j=heiMin;j<heiMax;j++){
1488 for(i=widMin;i<widMax;i++){
1489 if(pD1){
1490 switch(pD1->type){
1491 case 4:
1492 m=(unsigned char)pD2->pixdata[widthD*j+i];
1493 break;
1494 default:
1495 m=getpixid(pD1,i,j);
1496 break;
1497 }
1498 }
1499 else m=pD[widthD*j+i]; // CHARACTER
1500 pc[ipc++]=m; // STRING add to already-seen-sequence
1501 nn=nnstart; // index for pc[] used at comparing
1502 if(nn==0){ // first time and immediately after emit
1503 // for(k=0;k<ctSize;k++) if(color[k]==pc[nn]) break;
1504 k=pc[nn]; // equivalent to the above expression
1505 nn++;
1506 }
1507 else k=kstart; // code to be compared
1508 if(lzw){ // compress
1509 for(n=nstart;prec[n]!=-1;n++){ // matched upto and including nn-1 and n-1
1510 if(nn==ipc) break; // same as previously-seen-color-sequence
1511 if(prec[n]==k){
1512 if(color[n]==pc[nn]){
1513 nn++;
1514 k=n;
1515 }
1516 }
1517 }
1518 if(nn==ipc-1){ // if there is no previously-seen-color-sequence
1519 emit(k); // output code for hether-to matching sequence
1520 prec[n]=k; // add the code to dictionary
1521 color[n]=pc[ipc-1]; // add next-to-code-color in dictionary
1522 if(n>>bitsD) bitsD++;
1523 if(n==0xFFF){
1524 emit(clrcode);
1525 bitsD=bitsmin;
1526 for(n=0;n<4097;n++) prec[n]=-1;
1527 }
1528 pc[0]=m; // lastly-read color comes first in color array
1529 ipc=1;
1530 nnstart=0; //position of color array to be compared
1531 nstart=clrcode+2; // position of dictionary to be compared
1532 }
1533 else{ // when there is a previous instance
1534 nnstart=nn; // position of color array to be compared
1535 nstart=n; // position of dictionary to be compared
1536 kstart=k; // code to be compared
1537 }
1538 }
1539 else{ // not compress
1540 emit(m); // output code for hether-to matching sequence
1541 emit(clrcode);
1542 pc[0]=m; // lastly-read color comes first in color array
1543 ipc=1;
1544 nnstart=0; //position of color array to be compared
1545 }
1546 }
1547 }
1548 if(ipc==1){
1549 for(k=0;k<ctSize;k++) if(color[k]==pc[0]) break;
1550 }
1551 if(lzw) emit(k);
1552 n++;
1553 if(n>>bitsD) bitsD++;
1554
1555 emit(clrcode);
1556 bitsD=bitsmin;
1557
1558 emit(clrcode+1);
1559 i=bitPtrD/8;
1560 if((bitPtrD%8)!=0) i++;
1561 outbyte1(1,(char *)&i);
1562 outbyte1(i,(char *)outBufD);
1563 m=0;
1564 outbyte1(1,(char *)&m);
1565 m=0x3b;
1566 outbyte1(1,(char *)&m);
1567 outbyte1(-1,(char *)&m); /* for base64 encode */
1568 flush();
1569
1570 // delete[] prec;
1571 // delete[] color;
1572
1573 return 0;
1574}
1575
1576
1577void emit(int k)
1578{
1579 int i,j,m,n;
1580
1581 for(i=0;i<bitsD;i++){ // do for current number of bits
1582 m=bitPtrD/8; // put in n-th bit of m-th byte
1583 n=bitPtrD%8;
1584 j=k;
1585 j>>=i;
1586 j&=1;
1587 j<<=n;
1588 outBufD[m]|=j; // outBuf is char , j is int
1589 bitPtrD++;
1590 }
1591
1592 if(m>254){
1593 i=0xFF;
1594 outbyte1(1,(char *)&i);
1595 outbyte1(255,(char *)outBufD);
1596
1597 bitPtrD-=255*8;
1598 outBufD[0]=outBufD[255];
1599 outBufD[1]=outBufD[256];
1600 for(i=2;i<257;i++) outBufD[i]=0;
1601 }
1602}
1603
1604int PngOut()
1605{
1606 unsigned char signa[]={137,80,78,71,13,10,26,10};
1607 unsigned char *chunk;
1608
1609 int i,j,k,l,m,n;
1610 int i1,j1,k1,l1,m1,n1;
1611 int i2,j2,k2,l2,m2,n2;
1612 unsigned int step,red,green,blue;
1613 int lmatch,dmatch;
1614 int wdopen;
1615 unsigned long adler=1L;
1616 unsigned long s1,s2;
1617
1618 i=widthD*heightD/10;
1619 chunk=(unsigned char *)calloc(i*sizeof(char),sizeof(char)); /* this size must be related to picture size */
1620
1621
1622 outbyte(8,(char *)signa);
1623
1624 *(int *)&chunk[0]=13; // excluding length, type or crc
1625 revPng(&chunk[0]);
1626 chunk[4]='I';
1627 chunk[5]='H';
1628 chunk[6]='D';
1629 chunk[7]='R';
1630 *(int *)&chunk[8]=widthD;
1631 revPng(&chunk[8]);
1632 *(int *)&chunk[12]=heightD;
1633 revPng(&chunk[12]);
1634 chunk[16]=8; /* bit depth */
1635 chunk[17]=3; /* color type - palette index */
1636 chunk[18]=0; /* compression method - deflate */
1637 chunk[19]=0; /* filter method */
1638 chunk[20]=0; /* interlace method */
1639 crcPng(&chunk[4],17); // including chunk type and chunk data
1640 outbyte(25,(char *)chunk);
1641 *(int *)&chunk[0]=768; // 256*3
1642 revPng(&chunk[0]);
1643 chunk[4]='P';
1644 chunk[5]='L';
1645 chunk[6]='T';
1646 chunk[7]='E';
1647 l=8;
1648 step=0xFFFF/5;
1649 for(i=5;i>=0;i--){
1650 red=i*step;
1651 for(j=5;j>=0;j--){
1652 green=j*step;
1653 for(k=5;k>=0;k--){
1654 blue=k*step;
1655 if(i!=0||j!=0||k!=0){
1656 chunk[l++]=red;
1657 chunk[l++]=green;
1658 chunk[l++]=blue;
1659 }
1660 }
1661 }
1662 }
1663 step=0xFFFF/15;
1664 green=0;
1665 blue=0;
1666 for(i=14;i>0;i--){
1667 if(i%3!=0){
1668 red=i*step;
1669 chunk[l++]=red;
1670 chunk[l++]=green;
1671 chunk[l++]=blue;
1672 }
1673 }
1674 red=0;
1675 blue=0;
1676 for(i=14;i>0;i--){
1677 if(i%3!=0){
1678 green=i*step;
1679 chunk[l++]=red;
1680 chunk[l++]=green;
1681 chunk[l++]=blue;
1682 }
1683 }
1684 red=0;
1685 green=0;
1686 for(i=14;i>0;i--){
1687 if(i%3!=0){
1688 blue=i*step;
1689 chunk[l++]=red;
1690 chunk[l++]=green;
1691 chunk[l++]=blue;
1692 }
1693 }
1694 for(i=14;i>0;i--){
1695 if(i%3!=0){
1696 red=green=blue=i*step;
1697 chunk[l++]=red;
1698 chunk[l++]=green;
1699 chunk[l++]=blue;
1700 }
1701 }
1702 red=0;
1703 green=0;
1704 blue=0;
1705 chunk[l++]=red;
1706 chunk[l++]=green;
1707 chunk[l++]=blue;
1708 crcPng(&chunk[4],768+4);
1709 outbyte(780,(char *)chunk);
1710 for(l=0;l<780;l++) chunk[l]=0;
1711/** LZ77 conpression **/
1712 chunk[4]='I';
1713 chunk[5]='D';
1714 chunk[6]='A';
1715 chunk[7]='T';
1716 chunk[8]=0x78; /* compression method/flag code */
1717 chunk[9]=0x9c; /* additional flags/check bits */
1718 i1=10; // initial code byte
1719 j1=0; // initial bit position
1720 setPng(chunk,i1,j1,3,3,&i1,&j1); // three header bit for the block
1721 // final & fixed Huffman code
1722 l=heightD*widthD; /* insert filter type byte */
1723 for(n=heightD-1;n>=0;n--){
1724 k=n*(widthD+1);
1725 for(m=widthD;m>0;m--) pD[k+m]=pD[--l];
1726 pD[k]=0;
1727 }
1728 wdopen=0;
1729 l=heightD*(widthD+1);
1730 for(n=0;n<l;n++){
1731 lmatch=0;
1732 if(n<32768) wdopen=0;
1733 else wdopen=n-32768;
1734 for(m=n-1;m>=wdopen;m--){
1735 j=n;
1736 k=m;
1737 i=0;
1738 while(pD[j++]==pD[k++]){
1739 i++;
1740 if(i==258) break;
1741 if(j>=l) break;
1742 }
1743 if(i>lmatch){
1744 lmatch=i; /* length */
1745 dmatch=n-m; /* distance */
1746 }
1747 if(lmatch==258||j>=l) break;
1748 }
1749 l1=0; // number of extra bits
1750 m1=0; // value of extra bits
1751 if(lmatch<3) k1=pD[n]; // raw data
1752 else{
1753 if(lmatch<11) k1=254+lmatch;
1754 else if(lmatch<19){
1755 l1=1;
1756 k1=(lmatch-11)/2+265;
1757 m1=(lmatch-11)%2;
1758 }
1759 else if(lmatch<35){
1760 l1=2;
1761 k1=(lmatch-19)/4+269;
1762 m1=(lmatch-19)%4;
1763 }
1764 else if(lmatch<67){
1765 l1=3;
1766 k1=(lmatch-35)/8+273;
1767 m1=(lmatch-35)%8;
1768 }
1769 else if(lmatch<131){
1770 l1=4;
1771 k1=(lmatch-67)/16+277;
1772 m1=(lmatch-67)%16;
1773 }
1774 else if(lmatch<258){
1775 l1=5;
1776 k1=(lmatch-131)/32+281;
1777 m1=(lmatch-131)%32;
1778 }
1779 else k1=285;
1780 } /* else */
1781/* convert alphabet k1 to Huffman code */
1782 if(k1<144){
1783 n1=0x30+k1; // Huffman code
1784 i2=0x80; // mask for output
1785 }
1786 else if(k1<256){
1787 n1=0x190+k1-144;
1788 i2=0x100;
1789 }
1790 else if(k1<280){
1791 n1=0x0+k1-256;
1792 i2=0x40;
1793 }
1794 else{
1795 n1=0xc0+k1-280;
1796 i2=0x80;
1797 }
1798 for(;i2>0;i2/=2){
1799 if(n1&i2) setPng(chunk,i1,j1,1,1,&i1,&j1);
1800 else setPng(chunk,i1,j1,0,1,&i1,&j1);
1801 }
1802 if(l1>0) setPng(chunk,i1,j1,m1,l1,&i1,&j1); /* extra bits for length */
1803 if(k1>256){ /* distance in dmatch */
1804 m2=1;
1805 for(l2=1;;l2++){
1806 m2*=2;
1807 if(m2>=dmatch) break;
1808 }
1809 k1=l2*2-1; // code
1810 // dmatch<= k1 l2 extra-bits
1811 // 2 1 1 0
1812 // 4 3 2 0
1813 // 8 5 3 1
1814 // 16 7 4 2
1815 // 32 9 5 3
1816 l1=l2-2; // number of extra bits
1817 if(l1<0) l1=0;
1818 // m2 2 2 4 4 8 8 8 8 16 16 16
1819 // dmatch 1 2 3 4 5 6 7 8 9 10 11
1820 // l2 1 1 2 2 3 3 3 3 4 4 4
1821 // k1 1 1 3 3 5 5 5 5 7 7 7
1822 // l1 0 0 0 0 1 1 1 1 2 2 2 ->number of extra bits
1823 // n2 1 1 1 1 2 2 2 2 4 4 4
1824 // m2-n2 1 1 3 3 6 6 6 6 12 12 12
1825 // k1 0 (1) 2 (3) 4 4 (5) (5) 6 6 6 ->code
1826 // m2 1 2 3 4 6 6 8 8 12 12 12
1827 // m2-n2 0 1 2 3 4 4 6 6 8 8 8
1828 // m1 1 1 1 1 1 2 1 2 1 2 3
1829 // m1 0 0 0 0 0 1 0 1 0 1 2 ->extra bit value
1830 n2=pow(2,l1);
1831 if(dmatch<=m2-n2){
1832 k1--;
1833 m2=m2-n2;
1834 }
1835 m1=dmatch-(m2-n2);
1836 m1--; // value of extra bits
1837
1838 i2=0x10; // 5 bits
1839 for(;i2>0;i2/=2){
1840 if(k1&i2) setPng(chunk,i1,j1,1,1,&i1,&j1);
1841 else setPng(chunk,i1,j1,0,1,&i1,&j1);
1842 }
1843 if(l1>0) setPng(chunk,i1,j1,m1,l1,&i1,&j1); /* extra bits for distance */
1844 n+=lmatch-1; /* advance main loop counter - 1 incremented later */
1845 } /* if(k1>256) */
1846 } /* for(n=0;n<l;n++){ */
1847 i2=0x40; // 7 bits - end of block mark
1848 for(;i2>0;i2/=2){ // huffman code for 256 is 0
1849 if(0&i2) setPng(chunk,i1,j1,1,1,&i1,&j1);
1850 else setPng(chunk,i1,j1,0,1,&i1,&j1);
1851 }
1852/* Adler-32 : a check sum value of the uncompressed data */
1853 s1=adler&0xffff;
1854 s2=(adler>>16)&0xffff;
1855 for(n=0;n<l;n++){
1856 s1=(s1+pD[n])%65521;
1857 s2=(s2+s1)%65521;
1858 }
1859 if(j1!=0) i1++;
1860 *(unsigned long *)&chunk[i1]=(s2<<16)+s1;
1861 revPng(&chunk[i1]);
1862 i1+=4; /* pointer index to crc */
1863 *(int *)&chunk[0]=i1-8; /* data length */
1864 revPng(&chunk[0]);
1865 crcPng(&chunk[4],i1-4);
1866 i1+=4; /* number of bytes including crc */
1867 outbyte(i1,(char *)chunk);
1868 *(int *)&chunk[0]=0; /* data length */
1869 revPng(&chunk[0]);
1870 chunk[4]='I';
1871 chunk[5]='E';
1872 chunk[6]='N';
1873 chunk[7]='D';
1874 crcPng(&chunk[4],4);
1875 outbyte(12,(char *)chunk);
1876 flush();
1877
1878}
1879
1880void revPng(unsigned char *c)
1881{
1882 unsigned char a;
1883 a=c[0];
1884 c[0]=c[3];
1885 c[3]=a;
1886 a=c[1];
1887 c[1]=c[2];
1888 c[2]=a;
1889}
1890
1891/*********************************************
1892 Pad data into chunk
1893 chunk : chunk array
1894 byte : index into chunk array
1895 bit : bit position (0(lsb)-7(msb))
1896 val : data to be set
1897 nbit : number of bits of val
1898 *nxtbyte : next index to be returned
1899 *nxtbit : next bit position to be returned
1900********************************************/
1901void setPng(unsigned char *chunk,int byte,int bit,
1902 int val,int nbit,int *nxtbyte,int *nxtbit)
1903{
1904 unsigned char c1,c2;
1905 unsigned char cin[4];
1906 unsigned char mask,mask1;
1907 int sourcebyte,destbyte,sourcebit,destbit;
1908 int i;
1909
1910 sourcebyte=0;
1911 sourcebit=0;
1912 destbyte=byte;
1913 destbit=bit;
1914 *(unsigned long*)cin=val;
1915 for(i=0;i<nbit;i++){
1916 mask=1;
1917 mask<<=sourcebit;
1918 c1=cin[sourcebyte];
1919 if(c1&mask){
1920 mask=1;
1921 mask<<=destbit;
1922 chunk[destbyte]|=mask;
1923 }
1924 sourcebit++;
1925 if(sourcebit==8){
1926 sourcebyte++;
1927 sourcebit=0;
1928 }
1929 destbit++;
1930 if(destbit==8){
1931 destbyte++;
1932 destbit=0;
1933 }
1934 }
1935 *nxtbyte=destbyte;
1936 *nxtbit=destbit;
1937}
1938
1939
1940/**********************************************
1941 CRC - ported from W3C specification
1942 Return the CRC of the bytes buf[0]..[len-1]
1943 in buf[len]..[len+3]
1944**********************************************/
1945void crcPng(unsigned char *buf,int len)
1946{
1947 unsigned long c;
1948 int n,k;
1949
1950 if(!crc_table_computed){
1951 for(n=0;n<256;n++){
1952 c=(unsigned long)n;
1953 for(k=0;k<8;k++){
1954 if(c&1) c=0xedb88320L^(c>>1);
1955 else c=c>>1;
1956 }
1957 crc_table[n]=c;
1958 }
1959 crc_table_computed=1;
1960 }
1961 c=0xffffffffL;
1962 for(n=0;n<len;n++){
1963 c=crc_table[(c^buf[n])&0xff]^(c>>8);
1964 }
1965 *(int *)&buf[len]=c^0xffffffffL;
1966 revPng(&buf[len]);
1967}
1968
1969/**************************************************
1970 r,g,b - 0-100
1971**************************************************/
1972int WritePixel(int x,int y,int r,int g, int b)
1973{
1974 int i;
1975 if(x<cliplD) return; // clip rect left
1976 if(x>=cliprD) return;
1977 if(y<cliptD) return;
1978 if(y>=clipbD) return;
1979 i=StdColor(r,g,b);
1980 *(pD+y*widthD+x)=i;
1981}
1982
1983int WritePixel1(int xoff,int yoff)
1984{
1985 int x,y;
1986 x=xD+xoff;
1987 y=yD+yoff;
1988 if(x<cliplD) return; // clip rect left
1989 if(x>=cliprD) return;
1990 if(y<cliptD) return;
1991 if(y>=clipbD) return;
1992 *(pD+y*widthD+x)=coloD;
1993}
1994
1995/***************************************************
1996 frac - 0-255
1997***************************************************/
1998int WritePixel2(int xoff,int yoff,int frac)
1999{
2000 int x,y,r,g,b,r1,g1,b1,r2,g2,b2,co1,col1;
2001 x=xD+xoff;
2002 y=yD+yoff;
2003 if(x<cliplD) return; // clip rect left
2004 if(x>=cliprD) return;
2005 if(y<cliptD) return;
2006 if(y>=clipbD) return;
2007 col1=*(pD+y*widthD+x);
2008 r1=std256[col1][1];
2009 g1=std256[col1][2];
2010 b1=std256[col1][3];
2011 r2=std256[coloD][1];
2012 g2=std256[coloD][2];
2013 b2=std256[coloD][3];
2014 r=(r1*(255-frac)+r2*frac)/255;
2015 g=(g1*(255-frac)+g2*frac)/255;
2016 b=(b1*(255-frac)+b2*frac)/255;
2017 *(pD+y*widthD+x)=StdColorx(r,g,b);
2018}
2019
2020/***************************************************
2021 standard color index
2022 r1,g1,b1 - 0-100
2023***************************************************/
2024int StdColor(int r1,int g1,int b1)
2025{
2026 int i;
2027 int r,g,b;
2028
2029 r=r1*(0xffff/100);
2030 g=g1*(0xffff/100);
2031 b=b1*(0xffff/100);
2032 return StdColorx(r,g,b);
2033}
2034
2035int StdColorx(int r,int g,int b)
2036{
2037 int i;
2038
2039 if(r==0&&g==0&&b==0){
2040 return 255;
2041 }
2042 if(r==0xffff&&g==0xffff&&b==0xffff){
2043 return 0;
2044 }
2045 if(r==0&&g==0){
2046 i=(b+2185)/4369;
2047 if(i%3!=0){
2048 return 245-(i-i/3);
2049 }
2050 }
2051 if(g==0&&b==0){
2052 i=(r+2185)/4369;
2053 if(i%3!=0){
2054 return 225-(i-i/3);
2055 }
2056 }
2057 if(b==0&&r==0){
2058 i=(g+2185)/4369;
2059 if(i%3!=0){
2060 return 235-(i-i/3);
2061 }
2062 }
2063 if(b==g&&r==g){ // gray scale
2064 i=(g+2185)/4369;
2065 if(i!=0&&i%3!=0){
2066 return 255-(i-i/3);
2067 }
2068 }
2069 i=215-((r+6554)/13107)*36-((g+6554)/13107)*6-(b+6554)/13107;
2070 if(i==215) i=255;
2071 return i;
2072}
2073
2074void GifPatent() /* no more used */
2075{
2076 lzw=1;
2077}
2078
2079void ChangeSize(int deno)
2080{
2081 int i,j,k,l,m,n;
2082 int r,g,b;
2083
2084 widMin=0;
2085 widMax=widthD/2;
2086 heiMin=0;
2087 heiMax=heightD/2;
2088 for(j=0;j<heiMax;j++){
2089 for(i=0;i<widMax;i++){
2090 k=pD[widthD*j*2+i*2];
2091 l=pD[widthD*j*2+i*2+1];
2092 m=pD[widthD*(j*2+1)+i*2];
2093 n=pD[widthD*(j*2+1)+i*2+1];
2094 if(k==l&&l==m&&m==n){
2095 pD[widthD*j+i]=k;
2096 }
2097 else{
2098 r=(std256[k][1]+std256[l][1]+std256[m][1]+std256[n][1])/4;
2099 g=(std256[k][2]+std256[l][2]+std256[m][2]+std256[n][2])/4;
2100 b=(std256[k][3]+std256[l][3]+std256[m][3]+std256[n][3])/4;
2101 pD[widthD*j+i]=StdColorx(r,g,b);
2102 }
2103 }
2104 }
2105 i=GifOut();
2106}
2107
2108void GifSave(int num)
2109{
2110 double ratio;
2111 FILE *fp;
2112 int i,j,k,l,m,n;
2113 int *nent;
2114 int r,g,b,r1,g1,b1;
2115 int wid,hei;
2116 int wid1,hei1;
2117
2118 saveG=1; /* output and save */
2119 saveG=2;
2120 strcpy(saveGfn,"pc/o"); /* original */
2121 sprintf(&saveGfn[4],"%04i",num);
2122 strcat(saveGfn,".gif");
2123 gfp=fopen(saveGfn,"wb");
2124 GifOut();
2125 fclose(gfp);
2126 saveG=2; /* save */
2127 saveG=1;
2128 if(widthD*heightD<3000){ /* the original is smaller than thumbnail */
2129 gfp=fopen(saveGfn,"rb");
2130 saveGfn[3]='t';
2131 fp=fopen(saveGfn,"wb");
2132 while((i=fgetc(gfp))!=EOF) fputc(i,fp);
2133 fclose(fp);
2134 fclose(gfp);
2135 outbyte(16,"thumbnail saved\n");
2136 flush();
2137 return;
2138 }
2139 ratio=3000./(widthD*heightD);
2140 ratio=sqrt(ratio);
2141 wid=ratio*widthD;
2142 hei=ratio*heightD;
2143 widMin=0;
2144 widMax=wid;
2145 heiMin=0;
2146 heiMax=hei;
2147 wid1=widthD;
2148 hei1=heightD;
2149 widthD=wid;
2150 heightD=hei;
2151
2152 pD3=pcreate(4,wid,hei);
2153 k=wid*hei;
2154 nent=(int *)calloc(k,sizeof(int));
2155 if(pD1){
2156 for(j=0;j<hei1;j++){
2157 m=ratio*j;
2158 if(m==hei) m--;
2159 for(i=0;i<wid1;i++){
2160 l=ratio*i;
2161 if(l==wid) l--;
2162 getpix(pD1,i,j,&r,&g,&b);
2163 getpix(pD3,l,m,&r1,&g1,&b1);
2164 n=nent[m*wid+l];
2165 r=(r1*n+r)/(n+1);
2166 g=(g1*n+g)/(n+1);
2167 b=(b1*n+b)/(n+1);
2168 putpix(pD3,l,m,r,g,b);
2169 nent[m*wid+l]++;
2170 }
2171 }
2172 }
2173 else{
2174 for(j=0;j<hei1;j++){
2175 m=ratio*j;
2176 if(m==hei) m--;
2177 for(i=0;i<wid1;i++){
2178 l=ratio*i;
2179 if(l==wid) l--;
2180 k=pD[wid1*j+i];
2181 r=std256[k][1]/256;
2182 g=std256[k][2]/256;
2183 b=std256[k][3]/256;
2184 getpix(pD3,l,m,&r1,&g1,&b1);
2185 n=nent[m*wid+l];
2186 r=(r1*n+r)/(n+1);
2187 g=(g1*n+g)/(n+1);
2188 b=(b1*n+b)/(n+1);
2189 putpix(pD3,l,m,r,g,b);
2190 nent[m*wid+l]++;
2191 }
2192 }
2193 }
2194 if(pD1){
2195 free(pD1);
2196 free(pD2);
2197 }
2198 pD1=pD3;
2199
2200 strcpy(saveGfn,"pc/t"); /* thumbnail */
2201 sprintf(&saveGfn[4],"%04i",num);
2202 strcat(saveGfn,".gif");
2203 gfp=fopen(saveGfn,"wb");
2204 GifOut();
2205 fclose(gfp);
2206}
2207