home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 286_02 / size.c < prev    next >
Text File  |  1989-05-25  |  9KB  |  336 lines

  1. #include <stdio.h>
  2. #include <fcntl.h>
  3. #include <sys\types.h>
  4. #include <io.h>
  5. #include <sys\stat.h>
  6. #include <stdlib.h>
  7.  
  8. #define ERROR (-1)
  9. #define FONTID 51
  10.  
  11. struct fontspec {
  12.     unsigned char width,inkwidth,height;
  13.       signed char leftmargin;
  14.     unsigned char topline,cellheight;
  15. };
  16.  
  17. struct fontspec fontinfo[256], outinfo[256];
  18.  
  19. unsigned char DOTVALUE[] =
  20.     0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001
  21. };
  22.  
  23. unsigned char bufi[4096], bufo[4096];
  24. int infn,outfn, mode=0, option=0;
  25.  
  26. main(argc,argv)
  27. int argc;
  28. char *argv[];
  29. {
  30.     int loop, count, ret;
  31.     char ch;
  32.  
  33.     argv++;
  34.     while (argc-- > 1 && *(*argv)++=='-') {
  35.         if (**argv) {
  36.             ch= *(*argv)++;
  37.             ret=atoi(*argv);
  38.         } else {
  39.             ch=0;
  40.         }
  41.         switch(ch) {
  42.         case 's':
  43.             if (ret > 2) {
  44.                 fprintf(stderr,"only 0, 1 or 2 can be used with -s\n");
  45.                 exit(1);
  46.             }
  47.             option=ret;
  48.             break;
  49.         case 'o':
  50.             if (ret > 4) {
  51.                 fprintf(stderr,"only 0 to 3 can be used with -o\n");
  52.                 exit(1);
  53.             }
  54.             mode=ret;
  55.             break;
  56.         default:
  57.             fprintf(stderr,"Unknow option -%c ** IGNORED **\n",ch);
  58.             break;
  59.         }
  60.         argv++;
  61.     }
  62.  
  63.     if (argc!=2) {
  64.         fprintf(stderr,"size: size [options] infile outfile\n\n");
  65.         fprintf(stderr,"Available options include:\n");
  66.         fprintf(stderr,"    -s0  reduce height to half\n");
  67.         fprintf(stderr,"    -s1  double the width\n");
  68.         fprintf(stderr,"    -s2  double the height\n\n");
  69.         fprintf(stderr,"-o option is used with reduction only\n");
  70.         fprintf(stderr,"    -o0  ink dominate\n");
  71.         fprintf(stderr,"    -o1  perfer ink\n");
  72.         fprintf(stderr,"    -o2  perfer space\n");
  73.         fprintf(stderr,"    -o3  space dominate\n");
  74.         exit(1);
  75.     }
  76.     (*argv)--;
  77.     if ((infn=open(argv[0],O_RDONLY | O_BINARY)) == ERROR) {
  78.         fprintf(stderr,"\nsize: Open file error -- %s\n",argv[0]);
  79.         exit(1);
  80.         }
  81.     if ((outfn=open(argv[1],O_CREAT | O_BINARY | O_TRUNC |O_WRONLY,
  82.                           S_IREAD | S_IWRITE))
  83.            == ERROR) {
  84.         fprintf(stderr,"\nsize: Create file error -- %s\n",argv[1]);
  85.         exit(1);
  86.         }
  87.     if ((count=read(infn,bufi,256)) <= 0) {
  88. errorexit:
  89.         fprintf(stderr,"Bad font file\n");
  90.     }
  91.     if (bufi[0]!=FONTID) goto errorexit;
  92.     for (loop=1; loop<=count; loop++) {
  93.         if (bufi[loop]==0) goto cont;
  94.     }
  95.     goto errorexit;
  96. cont:
  97.     loop++;
  98.     lseek(infn,(long) loop, SEEK_SET);
  99.     if (read(infn,bufi,16) != 16) {
  100.         fprintf(stderr,"\n\nPremature EOF!\n");
  101.         goto cleanup;
  102.     }
  103.     switch(bufi[0]) {
  104.     case 0:
  105.         process0();
  106.         break;
  107.     case 1:
  108.         process1();
  109.         break;
  110.     default:
  111.         fprintf(stderr,"Invalid Font Type\n!");
  112.     }
  113. cleanup:
  114.     close(infn);
  115.     close(outfn);
  116. }
  117.  
  118. process0()
  119. {
  120.     unsigned char temp1,temp2;
  121.     int loop1,loop2,nochar,charsize,outsize;
  122.     struct fontspec inspec, outspec;
  123.  
  124.     inspec.width=bufi[5];
  125.     inspec.inkwidth=bufi[6];
  126.     inspec.height=bufi[7];
  127.     inspec.leftmargin=bufi[8];
  128.     inspec.topline=bufi[9];
  129.     inspec.cellheight=bufi[10];
  130.     chgspec(&inspec, &outspec);
  131.     bufo[0]=FONTID;
  132.     for (loop1=1;loop1<15;) bufo[loop1++]=' ';
  133.     for (loop1=15;loop1<32;) bufo[loop1++]=0;
  134.     for (loop1=16;loop1<27;loop1++) bufo[loop1]=bufi[loop1-16];
  135.     bufo[21]=outspec.width;
  136.     bufo[22]=outspec.inkwidth;
  137.     bufo[23]=outspec.height;
  138.     bufo[24]=outspec.leftmargin;
  139.     bufo[25]=outspec.topline;
  140.     bufo[26]=outspec.cellheight;
  141.     write(outfn,bufo,32);
  142.     nochar=bufi[1]+(bufi[2]<<8);
  143.     charsize=((inspec.inkwidth+7)>>3)*inspec.height;
  144.     outsize=((outspec.inkwidth+7)>>3)*outspec.height;
  145.     while (nochar--) {
  146.         if (read(infn,bufi,charsize)!=charsize) {
  147.             fprintf(stderr,"\n\nPremature EOF!\n");
  148.             goto cleanup;
  149.         }    
  150.         size(&inspec,bufi,bufo);
  151.         write(outfn,bufo,outsize);
  152.     }
  153. cleanup: ;
  154. }
  155.  
  156. process1()
  157. {
  158.     unsigned char temp1,temp2;
  159.     int loop1,loop2,nochar,charsize,outsize;
  160.     unsigned char *curptr;
  161.     long filesize;
  162.  
  163.     bufo[0]=FONTID;
  164.     for (loop1=1;loop1<15;) bufo[loop1++]=' ';
  165.     for (loop1=15;loop1<32;) bufo[loop1++]=0;
  166.     for (loop1=16;loop1<24;loop1++) bufo[loop1]=bufi[loop1-16];
  167.     nochar=bufi[1]+(bufi[2]<<8);
  168.     if (read(infn,fontinfo,6*nochar)!=6*nochar) {
  169.         fprintf(stderr,"\n\nPremature EOF!\n");
  170.         goto cleanup;
  171.     }
  172.     filesize=0L;
  173.     for (loop1=0; loop1<nochar; loop1++) {
  174.         chgspec(&fontinfo[loop1],&outinfo[loop1]);
  175.         filesize+=(long)((outinfo[loop1].inkwidth+7)>>3)*outinfo[loop1].height;
  176.     }
  177.     bufo[21]=(unsigned char) (filesize & 0xff);
  178.     bufo[22]=(unsigned char) ((filesize>>8) & 0xff);
  179.     bufo[23]=(unsigned char) ((filesize>>16) & 0xff);
  180.     write(outfn,bufo,32);
  181.     if (write(outfn,outinfo,6*nochar)!=6*nochar) {
  182.         fprintf(stderr,"\nError writing File!\n");
  183.         goto cleanup;
  184.     }
  185.     for (loop1=0; loop1<nochar; loop1++) {
  186.         charsize=((fontinfo[loop1].inkwidth+7)>>3)*fontinfo[loop1].height;
  187.         outsize=((outinfo[loop1].inkwidth+7)>>3)*outinfo[loop1].height;
  188.         if (read(infn,bufi,charsize)!=charsize) {
  189.             fprintf(stderr,"\n\nPremature EOF!\n");
  190.             goto cleanup;
  191.         }    
  192.         size(&fontinfo[loop1],bufi,bufo);
  193.         write(outfn,bufo,outsize);
  194.     }
  195. cleanup: ;
  196. }
  197.  
  198. chgspec(in,out)
  199. struct fontspec *in, *out;
  200. {
  201.     switch(option) {
  202.     case 0:
  203.         out->width=in->width;
  204.         out->inkwidth=in->inkwidth;
  205.         out->height=(in->height+1)>>1;
  206.         out->topline=(in->topline+1)>>1;
  207.         out->cellheight=(in->cellheight+1)>>1;
  208.         out->leftmargin=in->leftmargin;
  209.         break;
  210.     case 1:
  211.         out->width=in->width<<1;
  212.         out->inkwidth=in->inkwidth<<1;
  213.         out->height=in->height;
  214.         out->topline=in->topline;
  215.         out->cellheight=in->cellheight;
  216.         out->leftmargin=in->leftmargin*2;
  217.         break;
  218.     case 2:
  219.         out->width=in->width;
  220.         out->inkwidth=in->inkwidth;
  221.         out->height=in->height<<1;
  222.         out->topline=in->topline<<1;
  223.         out->cellheight=in->cellheight<<1;
  224.         out->leftmargin=in->leftmargin;
  225.         break;
  226.     }
  227. }
  228.  
  229. size(spec,bufi,bufo)
  230. struct fontspec *spec;
  231. unsigned char *bufi, *bufo;
  232. {
  233.     switch(option) {
  234.     case 0:
  235.         RH2to1(spec,bufi,bufo);
  236.         break;
  237.     case 1:
  238.         EW1to2(spec,bufi,bufo);
  239.         break;
  240.     case 2:
  241.         EH1to2(spec,bufi,bufo);
  242.     }
  243. }
  244.  
  245. /* Reduce height in the ratio 2 to 1 */
  246. RH2to1(spec,bufi,bufo)
  247. struct fontspec *spec;
  248. unsigned char *bufi, *bufo;
  249. {
  250.     int loop1, loop2, count, wb, height;
  251.     unsigned int temp1, temp2;
  252.  
  253.     wb=(spec->inkwidth+7)>>3;   /* calculate width in byte */
  254.     height=spec->height;
  255.     if (height==0 || wb==0) return;
  256.     for (; height!=3 && height!=1 && height>0 ; height-=2, bufi+=wb) {
  257.       for (loop1=0; loop1 < wb ; loop1++, bufi++) {
  258.         switch(mode) {
  259.         case 0:
  260.         case 1:
  261.             *bufo++= *bufi | *(bufi+wb);
  262.             break;
  263.         case 2:
  264.         case 3:
  265.             *bufo++= *bufi & *(bufi+wb);
  266.             break;
  267.         }
  268.       }
  269.     }
  270.     if (height==1) {
  271.         for (loop1=0; loop1<wb; loop1++) *bufo++ = *bufi++;
  272.     } else {
  273.         for (loop1=0; loop1<wb; loop1++,*bufi++) {
  274.             switch(mode) {
  275.             case 0:
  276.             case 1:
  277.                 *(bufo+wb)= *(bufi+wb) | *(bufi+wb+wb);
  278.                 *bufo++ = *bufi | *(bufi+wb);
  279.                 break;
  280.             case 2:
  281.             case 3:
  282.                 *(bufo+wb)= *(bufi+wb) & *(bufi+wb+wb);
  283.                 *bufo++ = *bufi & *(bufi+wb);
  284.                 break;
  285.             }
  286.         }
  287.     }
  288. }
  289.  
  290. /* Enlarge width in the ratio 1 to 2 */
  291. EW1to2(spec,bufi,bufo)
  292. struct fontspec *spec;
  293. unsigned char *bufi, *bufo;
  294. {
  295.     int loop1, loop2, count, wb, height;
  296.     unsigned int temp1, temp2;
  297.  
  298.     wb=(spec->inkwidth+7)>>3;   /* calculate width in byte */
  299.     count=(((spec->inkwidth<<1)+7)>>3) & 0x01;
  300.     height=spec->height;
  301.     if (height==0 || wb==0) return;
  302.     for (;height>0; height--) {
  303.         for (loop1=0; loop1 < wb; loop1++, bufi++) {
  304.             temp1=0;
  305.             for (loop2=0; loop2<8; loop2++) {
  306.                 temp1 <<= 2;
  307.                 temp1 |= (*bufi & 0x80) ? 3 : 0;
  308.                 *bufi <<= 1;
  309.             }
  310.             *bufo++ = temp1 >> 8;
  311.             *bufo++ = temp1 & 0xff;
  312.         }
  313.         if (count) *bufo--;
  314.     }
  315. }
  316.  
  317. /* Enlarge height in the ratio 1 to 2 */
  318. EH1to2(spec,bufi,bufo)
  319. struct fontspec *spec;
  320. unsigned char *bufi, *bufo;
  321. {
  322.     int loop1, loop2, wb, height;
  323.  
  324.     wb=(spec->inkwidth+7)>>3;   /* calculate width in byte */
  325.     height=spec->height;
  326.     if (height==0 || wb==0) return;
  327.     for (;height>0; height--, bufo+=wb) {
  328.         for (loop1=0; loop1 < wb; loop1++, bufi++, bufo++) {
  329.             *(bufo+wb)= *bufo= *bufi;
  330.         }
  331.     }
  332. }
  333.  
  334.  
  335.