home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / grafik / disptiff / dtiff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-15  |  22.0 KB  |  915 lines

  1. /*****************************************************************************
  2.  DTIFF.C - DTIFF, Display Tag Image File Format.
  3.  Written by Tom Cervenka for Late Night Software, (c) 1988
  4.  All Rights Reserved.
  5.  *****************************************************************************/
  6.  
  7. /* #define DEBUG */
  8. /* #define NOGRAPH */
  9. /* #define EDEBUG */
  10.  
  11. #ifdef NOGRAPH
  12. #define TESTXRES 639
  13. #define TESTYRES 479
  14. #endif
  15.  
  16. #define ON 0
  17. #define OFF 1
  18.  
  19. /* SetOff() sets bit p to 1 in byte buffer */
  20. #define SetOff(buffer,p) (*(buffer+(p/8))|=(128>>(p%8)))
  21. /* IsOn() = 1 if the bit p in buffer buf is reset to 0 */
  22. #define IsOn(buf,p)   ( !(*(buf+(p/8)) & (128>>(p%8))) )
  23. /* IsPixOn() = 1 if the bit p in buffer buf is set to 1 */
  24. #define IsPixOn(buf,p)   ( (*(buf+(p/8)) & (128>>(p%8))) )
  25.  
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include "tiff.h"  /* Header file for TIFF routines form DEST TACS */
  29. #include "apptag.h" /* Another */
  30. #include <fcntl.h>
  31. #include <io.h>
  32. #include <alloc.h>
  33. #include <graphics.h>
  34. #include <conio.h>
  35. #include <ctype.h>
  36. #include <string.h>
  37.  
  38. #define FULRES_TYPE 1    /* More TIFF STUFF */
  39. #define SINGLE_PLANE 1   /* ""              */
  40.  
  41. #define TRUE 1
  42. #define FALSE 0
  43.  
  44. #define ONE 1L
  45.  
  46. /* Function Prototypes */
  47.  
  48. void main(int argc,char *argv[]);
  49. void close_tiff(int fh);
  50. void AsIs(void);
  51. void FitAll(void);
  52. void Syntax(void);
  53. void Help(void);
  54. int Lastline(int y,int yres);
  55. int FitIt(int fullres, int maxres, int *xs);
  56. int FindOn(char *buf, int i, int res);
  57. void MaskIt(char *buf, int res, int max, int *offs);
  58.  
  59. const char doc[]={"List 'DTIFF.DOC' for details."};
  60.  
  61. int fh,gdriver=DETECT,gmode,ErrorCode,MaxX,MaxY;
  62. int rows=0,cols=0,strips=0;
  63. long rowsize;
  64.  
  65. int rot=0,bestfit=TRUE,bkcolor=WHITE,pixcolor=BLUE;
  66.  
  67. int vgax=FALSE,vgaxx=720,vgaxy=512; /* Hi-res option for VGA */
  68.  
  69. LONGPTR imagebuf;
  70.  
  71. struct palettetype pal;
  72.  
  73. void main(int argc,char *argv[])
  74. {
  75.  
  76.  int i,lomode,himode;
  77.  char *cmd;
  78.  char tifname[128];
  79.  tifname[0]=0;
  80.  
  81. /* Evaluate Arguments */
  82.  
  83.  if(argc<=1)
  84.     {
  85.     Help();
  86.     exit(0);
  87.     }
  88.  
  89.  if(argc>6)
  90.      {
  91.     printf("Too many parameters.");
  92.     Syntax();
  93.     exit(1);
  94.     }
  95.  
  96. /* 1st arg is file name */
  97.  
  98.  strcat(tifname,argv[1]);
  99.  if(!strchr(tifname,'.')) strcat(tifname,".tif");
  100.  
  101.  fh=open(tifname,O_TEXT|O_BINARY);
  102.  if(fh==-1)
  103.     {
  104.     perror("Can't open the TIF file.");
  105.      Syntax();
  106.     exit(1);
  107.     }
  108.  
  109. /* the rest of the args are options */
  110.  
  111.  for(i=2;i<argc;i++)
  112.     {
  113.     cmd=argv[i];
  114.     if(*cmd==*"/")
  115.         {
  116.         cmd++;
  117.         switch (tolower(*cmd)) {
  118.                                          /* Rotate */
  119.             case 'r'    :    cmd++;
  120.                         rot=atoi(cmd);
  121.                         if(rot!=0 && rot!=90 && rot!=180 && rot!=270)
  122.                             {
  123.                             printf("Bad rotation.");
  124.                             Syntax();
  125.                             close(fh);
  126.                             exit(1);
  127.                             }
  128.                               break;
  129.                                                  /* AS IS */
  130.             case    'a'    :    if(strlen(cmd)>1)
  131.                             {
  132.                             printf("Bad option.");
  133.                             Syntax();
  134.                             close(fh);
  135.                             exit(1);
  136.                             }
  137.                         bestfit=0;
  138.                         break;
  139.                                                /* Use Graphics Driver d */
  140.             case 'd'  :    cmd++;
  141.                         if(!stricmp(cmd,"ATT")) gdriver=ATT400;
  142.                         if(!stricmp(cmd,"ATT400")) gdriver=ATT400;
  143. /*                        if(!stricmp(cmd,"PC3270")) gdriver=PC3270; */
  144.                         if(!stricmp(cmd,"VGA")) gdriver=VGA;
  145.                         if(!stricmp(cmd,"VGAX")) {gdriver=VGA;vgax=TRUE;}
  146.                         if(!stricmp(cmd,"HERC")) gdriver=HERCMONO;
  147.                         if(!stricmp(cmd,"IBM8514")) gdriver=IBM8514;
  148.                         if(!stricmp(cmd,"EGAMONO")) gdriver=EGAMONO;
  149.                         if(!stricmp(cmd,"EGA64")) gdriver=EGA64;
  150.                         if(!stricmp(cmd,"EGA")) gdriver=EGA;
  151.                         if(!stricmp(cmd,"MCGA")) gdriver=MCGA;
  152.                         if(!stricmp(cmd,"CGA")) gdriver=CGA;
  153.                         if(gdriver==DETECT)
  154.                             {
  155.                             printf("Bad graphics driver selected.");
  156.                             Syntax();
  157.                             close(fh);
  158.                             exit(1);
  159.                             }
  160.                         break;
  161.                                       /* hi-res vga horizontal resolution */
  162.             case 'h'    :    cmd++;
  163.                         vgaxx=abs(atoi(cmd));
  164.                               break;
  165.                                       /* hi-res vga vertical resolution */
  166.             case 'v'    :    cmd++;
  167.                         vgaxy=abs(atoi(cmd));
  168.                               break;
  169.  
  170.             default    :    printf("Bad option.");
  171.                         Syntax();
  172.                         close(fh);
  173.                         exit(1);
  174.             }
  175.         }
  176.     else
  177.         {
  178.         printf("Bad parameter.");
  179.         Syntax();
  180.         close(fh);
  181.         exit(1);
  182.         }
  183.      }
  184.  
  185. #ifdef DEBUG
  186.  printf("rotation = %d\n%s\n",rot,bestfit?"bestfit":"as is");
  187.  getch();
  188. #endif
  189.  
  190. /* Read IMAGE WIDTH (Columns) TAG */
  191.  
  192.  if(read_tag(fh,1,T_IMG_WIDTH,(long)&cols,(short)sizeof(cols))==0)
  193.     {
  194.      printf("No tag for columns. %s\n",doc);
  195.      close_tiff(fh);
  196.     close(fh);
  197.     exit(1);
  198.      }
  199.  
  200. /* Read IMAGE LENGTH (Rows) TAG */
  201.  
  202.  if(read_tag(fh,1,T_IMG_LENGTH,(long)&rows,(short)sizeof(rows))==0)
  203.     {
  204.      printf("No tag for rows. %s\n",doc);
  205.      close_tiff(fh);
  206.      close(fh);
  207.     exit(1);
  208.      }
  209.  
  210.  rowsize=((long)cols+7)/8;   /* Convert columns (bits) to bytes */
  211.  
  212.  imagebuf=farmalloc(rowsize);  /* Alloc row buffer */
  213.  if(imagebuf==NULL)
  214.      {
  215.     printf("Not enough RAM for image. %s\n",doc);
  216.     close_tiff(fh);
  217.     close(fh);
  218.     exit(1);
  219.     }
  220.  
  221. #ifdef DEBUG
  222.  
  223.  printf("Number of cols (horz) = %u\n",cols);
  224.  printf("Number of rows (vert) = %u\n",rows);
  225.  printf("Width of 1 row in bytes = %u\n",rowsize);
  226.  getch();
  227.  
  228. #endif
  229.  
  230. #ifndef NOGRAPH
  231.  
  232. /* detect graphics hardware is adapter was not specified */
  233.  
  234.  if(gdriver==DETECT)
  235.      detectgraph(&gdriver,&gmode);
  236.  
  237. #ifdef DEBUG
  238.  printf("coreleft=%u\n",coreleft());
  239. #endif
  240.  
  241.  ErrorCode=-1;
  242.  
  243. /* Register the Driver */
  244.  
  245.  switch (gdriver)
  246.     {
  247.  
  248.     case CGA        :
  249.     case MCGA        :       ErrorCode=registerbgidriver(CGA_driver);
  250.                     break;
  251.     case EGA        :
  252.     case EGA64    :
  253.     case EGAMONO    :
  254.     case VGA        :    ErrorCode=registerbgidriver(EGAVGA_driver);
  255.                     break;
  256.     case HERCMONO    :    ErrorCode=registerbgidriver(Herc_driver);
  257.                     break;
  258.     case ATT400    :    ErrorCode=registerbgidriver(ATT_driver);
  259.                     break;
  260. /*    case PC3270    :    ErrorCode=registerbgidriver(PC3270_driver);
  261.                     break; */
  262.     case IBM8514    :    ErrorCode=registerbgidriver(IBM8514_driver);
  263.                     break;
  264.  
  265.     }
  266.  
  267. #ifdef DEBUG
  268.  printf("coreleft=%u\n",coreleft());
  269. #endif
  270.  
  271.  
  272.  if(ErrorCode<0)
  273.      {
  274.      printf("Graphics System Error: Can't register driver. %s\n",doc);
  275.      farfree(imagebuf);
  276.      close_tiff(fh);
  277.     close(fh);
  278.         exit( 1 );
  279.     }
  280.  
  281. /* Set the graphics mode for the driver, we want highest spatial resolution */
  282.  
  283.  switch (gdriver)
  284.     {
  285.  
  286.     case CGA        :    gmode=CGAHI; break;
  287.     case MCGA        :       gmode=MCGAHI; break;
  288.     case EGA        :    gmode=EGAHI; break;
  289.     case EGA64    :    gmode=EGA64HI; break;
  290.     case EGAMONO    :    gmode=EGAMONOHI; break;
  291.     case VGA        :    gmode=VGAHI; break;
  292.     case HERCMONO    :    gmode=HERCMONOHI; break;
  293.     case ATT400    :    gmode=ATT400HI; break;
  294.     case IBM8514    :    gmode=IBM8514HI; break;
  295.     default        :;
  296.     }
  297.  
  298.  
  299.  /* Startup BGI */
  300.  
  301.  initgraph(&gdriver,&gmode,"");
  302.  ErrorCode = graphresult();        /* Read result of initialization*/
  303.  if( ErrorCode != grOk )        /* Error occured during init    */
  304.      {
  305.      printf("Graphics System Error: %s\n %s\n",grapherrormsg(ErrorCode),doc);
  306.      farfree(imagebuf);
  307.      close_tiff(fh);
  308.     close(fh);
  309.         exit(1);
  310.     }
  311.  
  312.  if(vgax)
  313.     {
  314.     char *vgaxmsg;
  315.     if((vgaxmsg=vgaxset(vgaxx,vgaxy,0)))
  316.         {
  317.         closegraph();
  318.         printf("Graphics System Error: %s\n %s\n",vgaxmsg,doc);
  319.         farfree(imagebuf);
  320.         close_tiff(fh);
  321.         close(fh);
  322.         exit(1);
  323.         }
  324.     }
  325.  
  326.  MaxX=getmaxx();
  327.  MaxY=getmaxy();
  328.  
  329.  if(vgax)
  330.     {
  331.     MaxX=vgaxx-1;
  332.     MaxY=vgaxy-1;
  333.     }
  334.  
  335. #else
  336.  MaxX=TESTXRES;
  337.  MaxY=TESTYRES;
  338. #endif
  339.  
  340. #ifdef DEBUG
  341.  if(gdriver==HERCMONO)
  342.     {
  343. #ifndef NOGRAPH
  344.     restorecrtmode();
  345. #endif
  346.     }
  347.  
  348.  printf("screen cols=%d screen rows=%d\n",MaxX,MaxY);
  349.  getch();
  350.  
  351.  if(gdriver==HERCMONO)
  352.     {
  353. #ifndef NOGRAPH
  354.     setgraphmode(getgraphmode());  /* Set the mode */
  355. #endif
  356.     }
  357. #endif
  358.  
  359. #ifndef NOGRAPH
  360.  if(gdriver==EGA64 || gdriver==EGA || gdriver==VGA)
  361.     {
  362.      getpalette(&pal);             /* Change palette to get background light */
  363.      setpalette(0,EGA_WHITE);      /* and image dark for EGA/VGA systems */
  364.      setpalette(15,EGA_BLACK);
  365.     setpalette(1,EGA_BLACK);
  366.     pixcolor=15; if(gdriver==EGA64) pixcolor=1;
  367.     }
  368.  else
  369.      if(gdriver!=HERCMONO && gdriver!=CGA && gdriver!=MCGA && gdriver!=EGAMONO)
  370.         {
  371.         setbkcolor(bkcolor);  /* Change background color for others */
  372.         }
  373.  if(gdriver==HERCMONO || gdriver==CGA || gdriver==ATT400 || gdriver==MCGA || gdriver==EGAMONO)
  374.     {
  375.     setcolor(1); if(gdriver==EGAMONO) setcolor(3);
  376.     rectangle(0,0,getmaxx(),getmaxy());
  377.     setfillstyle(SOLID_FILL,1); if(gdriver==EGAMONO) setfillstyle(SOLID_FILL,3);
  378.     floodfill(1,1,1); if(gdriver==EGAMONO) floodfill(1,1,3);
  379.     pixcolor=0;
  380.     setcolor(0);
  381.     }
  382.  else
  383.     {
  384.     /* if(!vgax) */ cleardevice();
  385.     }
  386. #endif
  387.  
  388.  if(bestfit)
  389.     FitAll();
  390.  else
  391.     AsIs();
  392.  getch();
  393. #ifndef NOGRAPH
  394.  if(gdriver==EGA64 || gdriver==EGA || gdriver==VGA)
  395.      setallpalette(&pal);
  396.  closegraph();
  397. #endif
  398.  farfree(imagebuf);
  399.  close_tiff(fh);
  400.  close(fh);
  401. }
  402.  
  403. /*****************************************************************************
  404.  AsIs() displays image starting at col 0 to col (MaxCols of adapter) and from
  405.  row 0 to row (MaxRows of adapter). If image is larger than adapter, image
  406.  will not be completely displayed
  407.  ****************************************************************************/
  408.  
  409. void AsIs(void)
  410. {
  411.  int linecount,x,y,i,xres,yres,xstart,xmove,ymove;
  412.  long startpos;
  413.  unsigned char k,mask,pix;
  414.  
  415. /* set coordinates depending on rotation
  416.    xres=column resolution
  417.    yres=row resolution
  418.    xstart=starting column
  419.    y=starting row
  420.    xmove=value to change xstart after pixel is written
  421.    ymove=value to change ystart after pixel is written */
  422.  
  423.  switch (rot)
  424.     {
  425.      case 0    :    (cols>MaxX) ? (xres=MaxX) : (xres=cols);
  426.                 (rows>MaxY) ? (yres=MaxY) : (yres=rows);
  427.                 xstart=0;
  428.                 y=0;
  429.                 xmove=1;
  430.                 ymove=1;
  431.                 break;
  432.  
  433.     case 90    :    (cols>MaxY) ? (xres=MaxY) : (xres=cols);
  434.                 (rows>MaxX) ? (yres=MaxX) : (yres=rows);
  435.                 xstart=xres-1;
  436.                 y=0;
  437.                 xmove=-1;
  438.                 ymove=1;
  439.                 break;
  440.  
  441.     case 180    :    (cols>MaxX) ? (xres=MaxX) : (xres=cols);
  442.                 (rows>MaxY) ? (yres=MaxY) : (yres=rows);
  443.                 xres=MaxX;
  444.                 yres=MaxY;
  445.                 xstart=xres-1;
  446.                 y=yres-1;
  447.                 xmove=-1;
  448.                 ymove=-1;
  449.                 break;
  450.  
  451.     case 270    :    (cols>MaxY) ? (xres=MaxY) : (xres=cols);
  452.                 (rows>MaxX) ? (yres=MaxX) : (yres=rows);
  453.                 xstart=0;
  454.                 y=yres-1;
  455.                 xmove=1;
  456.                 ymove=-1;
  457.                 break;
  458.     }
  459.  
  460. #ifdef DEBUG
  461.  printf("xres=%d yres=%d y=%d xstart=%d xmove=%d ymove=%d",
  462.         xres,yres,y,xstart,xmove,ymove);
  463.  getch();
  464. #endif
  465.  
  466.  linecount=rows; /* counts down to zero */
  467.  startpos=0;     /* row to read starts at 0 */
  468.  
  469. /* display image row by row until 1) image is done or 2) no more rows left on
  470.    the display or 3) a key is hit */
  471.  
  472.  while(linecount>0 && Lastline(y,yres) && !kbhit())
  473.      {
  474.     if(read_image(fh,FULRES_TYPE,SINGLE_PLANE, /* read image 1 row at a time */
  475.               startpos,ONE,
  476.                   imagebuf,rowsize)==NULL)
  477.             {
  478.         farfree(imagebuf);
  479.           getch();
  480.           closegraph();
  481.         close_tiff(fh);
  482.           close(fh);
  483.         printf("Error reading image line %u\n%s\n",rows-linecount+1,doc);
  484.         exit(1);
  485.         }
  486.     x=xstart;  /* reset starting column before column loop */
  487.  
  488. /* Column loop */
  489.  
  490.     for(i=0;i<=xres/8;i++) /* byte loop */
  491.         for(k=0,mask=128;k<8;k++,mask=mask>>1)  /* bit loop */
  492.             {
  493.             pix=*(imagebuf+i);
  494.             pix=pix & mask;
  495.             if(pix)
  496. #ifndef NOGRAPH
  497.                 {
  498.                 if(gdriver==ATT400 || gdriver==IBM8514 || gdriver==MCGA || gdriver==EGAMONO)
  499.                     (rot==0 || rot==180) ? (putpixel(x,y,pixcolor)) :
  500.                                    (putpixel(y,x,pixcolor)) ;
  501.                 else
  502.                     {
  503.                     if(gdriver==VGA || gdriver==EGA64 || gdriver==EGA)
  504.                         {
  505.                         (rot==0 || rot==180) ? (vgaxputpixel(x,y,pixcolor)) :
  506.                                            (vgaxputpixel(y,x,pixcolor)) ;
  507.                         }
  508.                     else
  509.                         {
  510.                         if(gdriver==HERCMONO)
  511.                             {
  512.                             (rot==0 || rot==180) ? (hercputpixel(x,y,pixcolor)) :
  513.                                                (hercputpixel(y,x,pixcolor)) ;
  514.                             }
  515.                         else
  516.                             {
  517.                             (rot==0 || rot==180) ? (cgaputpixel(x,y,pixcolor)) :
  518.                                                (cgaputpixel(y,x,pixcolor)) ;
  519.                             }
  520.                         }
  521.                     }
  522.                 }
  523. #endif
  524. #ifdef DEBUG
  525. #ifdef NOGRAPH
  526.  printf("%s\n",(rot==0 || rot==180) ? "(putpixel(x,y,BLUE)" :
  527.                                "(putpixel(y,x,BLUE)") ;
  528.  if(getch()==*"s") exit(0);
  529. #endif
  530. #endif
  531.             x+=xmove; /* increment column position */
  532.             }
  533.     y+=ymove;    /* increment row position */
  534.     linecount--;  /* next line */
  535.     startpos++;   /*    ""     */
  536.     }
  537. }
  538.  
  539. /*****************************************************************************
  540.  Returns FALSE if value row position y is out of bounds for adapter.
  541.  This condition depends on the rotation of the image
  542.  ****************************************************************************/
  543.  
  544. int Lastline(int y,int yres)
  545. {
  546.  if(rot==90 || rot==180)
  547.      {
  548.     if (y>=0) return(TRUE);
  549.     else return(FALSE);
  550.      }
  551.  else
  552.     {
  553.     if(y<=yres) return(TRUE);
  554.     else return(FALSE);
  555.     }
  556. }
  557.  
  558. /* Fitall() displays the entire image on the display by masking out columns and
  559.    rows until it fits in the bounds of the adapter. Fitall() doesn't mask if the
  560.    image fits in the display. */
  561.  
  562. void Fitall(void)
  563. {
  564.  
  565.  char *cbuf,*rbuf;
  566.  int linecount,x,y,i,cres,rres,xstart,xmove,ymove,rcnt,coffs,roffs,cmax,rmax;
  567.  long startpos;
  568.  
  569.  
  570.  cbuf=calloc(cols+1,sizeof(char));  /* alloc column mask buffer */
  571.  if(cbuf==NULL)
  572.      {
  573.     farfree(imagebuf);
  574.      closegraph();
  575.     close_tiff(fh);
  576.      close(fh);
  577.     printf("Can't allocate space for the column mask.\n%s\n",doc);
  578.     exit(1);
  579.     }
  580.  coffs=0;
  581.  
  582.  rbuf=calloc(rows+1,sizeof(char)); /* alloc row mask buffer */
  583.  if(rbuf==NULL)
  584.      {
  585.     farfree(imagebuf);
  586.      closegraph();
  587.     close_tiff(fh);
  588.      close(fh);
  589.     printf("Can't allocate space for the row mask.\n%s\n",doc);
  590.      free(cbuf);
  591.     exit(1);
  592.     }
  593.  roffs=0;
  594.  
  595. /* set coordinates depending on rotation
  596.    cmax=column resolution
  597.    rmax=row resolution
  598.    xstart=starting column
  599.    y=starting row
  600.    xmove=value to change xstart after pixel is written
  601.    ymove=value to change ystart after pixel is written */
  602.  
  603.  switch (rot)
  604.     {
  605.      case 0    :    cmax=MaxX+1;
  606.                 rmax=MaxY+1;
  607.                 xstart=0;
  608.                 y=0;
  609.                 xmove=1;
  610.                 ymove=1;
  611.                 break;
  612.  
  613.     case 90    :    cmax=MaxY+1;
  614.                 rmax=MaxX+1;
  615.                 xstart=cmax;
  616.                 y=0;
  617.                 xmove=-1;
  618.                 ymove=1;
  619.                 break;
  620.  
  621.     case 180    :    cmax=MaxX+1;
  622.                 rmax=MaxY+1;
  623.                 xstart=cmax;
  624.                 y=rmax;
  625.                 xmove=-1;
  626.                 ymove=-1;
  627.                 break;
  628.  
  629.     case 270    :    cmax=MaxY+1;
  630.                 rmax=MaxX+1;
  631.                 xstart=0;
  632.                 y=rmax;
  633.                 xmove=1;
  634.                 ymove=-1;
  635.                 break;
  636.     }
  637.  
  638.  MaskIt(cbuf,cols,cmax,&coffs); /* build column mask */
  639.  MaskIt(rbuf,rows,rmax,&roffs); /* build row mask */
  640.  
  641.  linecount=rows;
  642.  startpos=0;
  643.  rcnt=0;     /* row mask buffer position */
  644.  
  645. /* display image row by unmaked row until done or key is hit */
  646.  
  647.  while(linecount>0 && !kbhit())
  648.      {
  649.     if(IsOn(rbuf,rcnt))  /* display row if not masked */
  650.         {
  651.         if(read_image(fh,FULRES_TYPE,SINGLE_PLANE,  /* read one row at a time */
  652.                     startpos,ONE,
  653.                       imagebuf,rowsize)==NULL)
  654.                 {
  655.             farfree(imagebuf);
  656.             getch();
  657.               closegraph();
  658.             close_tiff(fh);
  659.               close(fh);
  660.             printf("Error reading image line %u\n%s\n",rows-linecount+1,doc);
  661.             exit(1);
  662.             }
  663.           x=xstart;            /* reset column position */
  664.         for(i=0;i<=cols;i++) /* column loop */
  665.             {
  666.             if(IsOn(cbuf,i)) /* check pixel if not masked */
  667.                 {
  668.                 if(IsPixOn(imagebuf,i)) /* display pixel if on */
  669. #ifndef NOGRAPH
  670.                     {
  671.                     if(gdriver==ATT400 || gdriver==IBM8514 || gdriver==MCGA || gdriver==EGAMONO )
  672.                         (rot==0 || rot==180) ? (putpixel(x,y,pixcolor)) :
  673.                                            (putpixel(y,x,pixcolor)) ;
  674.                     else
  675.                         {
  676.                         if(gdriver==VGA || gdriver==EGA64 || gdriver==EGA)
  677.                             {
  678.                             (rot==0 || rot==180) ? (vgaxputpixel(x,y,pixcolor)) :
  679.                                                (vgaxputpixel(y,x,pixcolor)) ;
  680.                             }
  681.                         else
  682.                             {
  683.                             if(gdriver==HERCMONO)
  684.                                 (rot==0 || rot==180) ? (hercputpixel(x,y,pixcolor)) :
  685.                                                    (hercputpixel(y,x,pixcolor)) ;
  686.                             else
  687.                                 {
  688.                                 (rot==0 || rot==180) ? (cgaputpixel(x,y,pixcolor)) :
  689.                                                    (cgaputpixel(y,x,pixcolor)) ;
  690.                                 }
  691.                             }
  692.                         }
  693.                     }
  694. #endif
  695.                 x+=xmove; /* next column */
  696.                 }
  697.             }
  698.         y+=ymove; /* next row */
  699.         }
  700.     rcnt++; /* next row mask buffer position */
  701.     linecount--; /* next image row */
  702.     startpos++; /*  next image row */
  703.     }
  704.  
  705.  free(rbuf);  /* dealloc row mask buffer */
  706.  free(cbuf);  /* dealloc col mask buffer */
  707.  
  708. #ifdef DEBUG
  709.  getch();
  710.  closegraph();
  711.  printf("\n%d columns, Skipped %d , DisplayedONs=%d, picture=%d\n\n",
  712.         cmax,coffs,cols-coffs,cols);
  713.  printf("\n%d rows, Skipped %d , DisplayedONs=%d, picture=%d\n\n",
  714.         rmax,roffs,rows-roffs,rows);
  715.  getch();
  716. #endif
  717.  
  718. }
  719.  
  720. int FitIt(int fullres, int maxres, int *xs)
  721. {
  722. /*****************************************************************************
  723.  Provides information necessary to squeeze a large picture onto a small screen
  724.  Input:
  725.         fullres - resolution of the picture in dots or pixels
  726.         maxres  - maximum resolution (in one direction) of the display
  727.  Output:
  728.         *xs - number of picture dots in a row to skip when displaying.
  729.              this is repeated for entire picture. For example, if *xs=2,
  730.              you should skip 2 dots then display one for the entire picture.
  731.              if *xs=0 then no dots should be skipped this way.
  732.  
  733.  Return:
  734.         the number of dots to display before skipping 1 dot. again this
  735.         pattern is reapeted for the length of the picture.
  736.  
  737.         **NOTE** if the return value==0, then no dots should be skipped this
  738.         way.
  739. *****************************************************************************/
  740.  
  741.  int b,quo,rem,ll,c1,c2;
  742.  
  743.  *xs=b=0; /*Init to no skips*/
  744.  
  745.  quo=fullres/maxres; /* quo is the fraction of the picture that'll fit on the */
  746.  rem=fullres%maxres; /* screen. rem>0 if there are dots left over */
  747.  
  748.  if(quo>1)
  749.     *xs=quo-1; /* changes into the number of repeating skips - if quo=3 we */
  750.  else           /* want to skip 2, display 1 */
  751.     if(quo==0) quo++; /* quo==1 means that the whole picture fits on the */
  752.                    /* screen with the possible exception of rem dots. */
  753.  
  754.  if(rem) /* check for left over dots */
  755.     {
  756.      ll=fullres/quo;
  757.     rem=ll-maxres;              /* set rem to the number of not skipped by
  758.                                   *xs and subtract maxres to find out how
  759.                             many more dots must be skipped */
  760.  
  761.     if(rem>0) b=ll/rem;                /* then divide this into the remaining
  762.                                 lines to evenly distribute the
  763.                                 leftovers if there are any */
  764.      c1=ll-(ll/(b+1));
  765.     if(c1>maxres)
  766.         {
  767.         c2=ll-(ll/b);
  768.         if(abs(maxres-c2)<abs(maxres-c1)) b--;
  769.         }
  770.  
  771.     }
  772.  
  773.  return(b);
  774. }
  775.  
  776.  
  777. int FindOn(char *buf, int i, int res)
  778. {
  779.  char mask;
  780.  
  781.  if(i<0) return(i); /* invalid dot */
  782.  
  783.  do    {
  784.  
  785.      /* each dot is stored in a byte in the buffer, this is how to find the
  786.        value of the bit that corresponds to the dot (i), if mask==0 then the
  787.        dot will be diplayed (ON) else if mask==1 the dot will be skipped
  788.        because if is (OFF);                                                */
  789.  
  790.      mask=*(buf+(i/8)) & (128>>(i%8));
  791.  
  792.     i++; /* next dot */
  793.     }
  794.  while(mask!=ON && i<=res+1); /* search all dots */
  795.  
  796.  if(mask==ON && i<=res+1)    /* valid ON dot */
  797.     {
  798.     i--;                    /* fixup dot position */
  799.     return(i);
  800.     }
  801.  else
  802.     return(-9);    /* no ON dots were found so return some negative number */
  803.  
  804. }                                                 /* end of FindOn */
  805.  
  806. void MaskIt(char *buf, int res, int max, int *offs)
  807. {
  808.  int blk,cnt,skp;
  809.  register i;
  810.  
  811.  blk=FitIt(res,max,&skp); /* get the info about dots to skip */
  812.  
  813.  if(blk==0 && skp==0)
  814.     return;            /* nothing to skip, assume all dots are ON */
  815.  
  816.  if(skp)    /* repeating skips */
  817.     {
  818.  
  819.     i=0; /* first dot */
  820.     while(i<=res && i>=0)    /* go through all dots */
  821.         {
  822.  
  823.         for(cnt=0;cnt<skp && (i>=0 && i<=res);cnt++)
  824.             {
  825.             i=FindOn(buf,i,res); /* find the next ON dot */
  826.  
  827.             if(i>=0)             /* check for a valid dot */
  828.                 {
  829.                 SetOff(buf,i);   /* set the dot OFF */
  830.  
  831.                 (*offs)++;      /* increment OFF count */
  832.                 i++;            /* i = next dot */
  833.                 }
  834.                }
  835.         i=FindOn(buf,i,res); /* find the next ON dot */
  836.         i++;                 /* and skip it */
  837.  
  838.         }
  839.     }                                             /* end of repeating skips */
  840.  
  841.  
  842.  if(blk) /* number of dots to display, then turn one OFF */
  843.     {
  844.     i=0; /* first dot */
  845.     while(i<=res && i>=0)    /* go through all dots */
  846.          {
  847.         for(cnt=0;cnt<blk && (i>=0 && i<=res);cnt++)
  848.             {
  849.             i=FindOn(buf,i,res); /* find next ON dot */
  850.  
  851.             if(i>=0)
  852.                 i++;     /* if i is valid, skip to the next dot */
  853.             }
  854.  
  855.         i=FindOn(buf,i,res); /* this is the dot to skip */
  856.  
  857.           if(i>=0)
  858.             {
  859.             SetOff(buf,i);
  860.             (*offs)++;     /* increment OFF count */
  861.  
  862.             i++;
  863.             }
  864.         }
  865.     }                                      /* end of display dots, skip one */
  866.  
  867. }                                /* end of MaskIt */
  868.  
  869.  
  870.  
  871.  
  872. void close_tiff(int fh)
  873. {
  874. #ifdef DEBUG
  875.  printf("In close_tiff\n");
  876.  getch();
  877. #endif
  878.  if(!close_read(fh))
  879.     printf("error closing read routines");
  880. }
  881.  
  882. void Help(void)
  883. {
  884.  printf("\n\n"
  885. "DTIFF - Display Tag Image File Format, Version 2.0 (c) 1988 Late Night Software\n"
  886. "\n"
  887. "DTIFF is a utility that displays TIFF file images on systems that have a CGA,\n"
  888. "EGA, VGA, MCGA, Hercules, IBM 8514/A, or AT&T display adapter cards.\n"
  889. "The command to use is:\n"
  890. "\n"
  891. "                     dtiff <tiff file> [ options ]\n"
  892. "Where:\n"
  893. "<tiff file> is the DOS name of the Tag Image File Format to display.\n"
  894. "[options] are separated by a space and begin with a '/'. They are:\n"
  895. "\n"
  896. "        /rn   : Rotate the the picture 'n' degrees, n=0,90,180 or 270\n"
  897. "\n"
  898. "        /a    : Display the picture 'as is'. If the picture is larger than\n"
  899. "                your display, you'll will see only a portion of it.\n"
  900. "\n"
  901. "        /dADP : Use the adapter 'ADP', ADP=CGA,MCGA,EGA,EGA64,EGAMONO,VGA,\n"
  902. "                IBM8514,HERC,or ATT. If not specified, DTIFF will try to \n"
  903. "                detect the type of adapter that is installed in your system.\n"
  904. "\n"
  905. "List the file 'DTIFF.DOC' for more detailed information.\n"
  906. "Late Night Software, PO BOX 81471, Chicago, IL  60681-0471\n\n");
  907. }
  908.  
  909. void Syntax(void)
  910. {
  911.  printf("\n\nDo you want to see the instructions? If so, press 'Y' -> ");
  912.  if(tolower(getch())==*"y")
  913.     Help();
  914. }
  915.