home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 625.lha / STScan_v2.0 / imginout.c < prev    next >
C/C++ Source or Header  |  1992-02-22  |  23KB  |  696 lines

  1. /* imginout.c input/output routines for stscan.c */
  2. #include <exec/exec.h>
  3. #include <exec/types.h>
  4. #include <intuition/intuition.h>
  5. #include <intuition/intuitionbase.h>
  6. #include <libraries/dos.h>
  7. #include <libraries/dosextens.h>
  8. #include <graphics/rastport.h>
  9. #include <libraries/reqbase.h>
  10. #include <req_pragmas.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <functions.h>
  14. #include "stscan.h"
  15.  
  16. #define ST400LUN 96
  17. #define DEV_NAME (char*)"scsi.device" /* <- change for other SCSI controller */
  18. #define FORM 0x464f524d
  19. #define ILBM 0x494c424d
  20. #define BMHD 0x424d4844
  21. #define BODY 0x424f4459
  22. #define DIR_READ  1
  23. #define DIR_WRITE 0
  24.  
  25. /* Scanner specific sizes and commands */
  26.  
  27. static UWORD cornerxval[]={  22,  33,  44, 266, 399, 535};
  28. static UWORD corneryval[]={   6,   6,   6,   6,   6,   6};
  29. static UWORD widthval[]=  {1664,2496,3312,1168,1760,2336};
  30. static UWORD heightval[]= {2336,3504,4672,1656,2484,3312};
  31.  
  32. static UBYTE cmd_scan[]={0x1b,ST400LUN,0,0,0,0};
  33. static UBYTE cmd_read[]={0x28,ST400LUN,0,0,0,0,0,0,0,0};
  34. static UBYTE cmd_dwin[]={0x24,ST400LUN,0,0,0,0,0,0,40,0};
  35. static UBYTE cmd_mdon[]={0x15,ST400LUN,0,0,0,128};
  36. static UBYTE cmd_mdoff[]={0x15,ST400LUN,0,0,0,0};
  37. static UBYTE cmd_inqu[]={0x12,ST400LUN,0,0,96,0};
  38.  
  39. /* IFF-ILBM Constants */
  40.  
  41. static UBYTE iff_cmap_bw[]=
  42. {'C','M','A','P',0,0,0,6,0,0,0,255,255,255};
  43.  
  44. static UBYTE iff_cmap_gray[]=
  45. {'C','M','A','P',0,0,0,48,0,0,0,16,16,16,32,32,32,48,48,48,64,64,64,80,80,80,
  46.  96,96,96,112,112,112,128,128,128,144,144,144,160,160,160,176,176,176,
  47.  192,192,192,208,208,208,224,224,224,240,240,240};
  48.  
  49. static ULONG iff_head[]={FORM,0,ILBM,BMHD,20,0,0,0,0x00000101,0x02800200};
  50.  
  51. static ULONG iff_body[]={BODY,0};
  52.  
  53. static ULONG chunk_hd[2];
  54.  
  55. typedef struct iffhead
  56. { ULONG iff_magic;
  57.   ULONG filelen;
  58.   ULONG ilbm_magic;
  59.   ULONG bmhd_magic;
  60.   ULONG bmhd_len;
  61.   UWORD w,h,x,y;
  62.   UBYTE d, mask, cmp, pad;
  63.   UWORD transparent,aspect,pw,ph;
  64. };
  65.  
  66. static struct iffhead iffheader;
  67.  
  68. UBYTE sk;
  69. UWORD vx,vy;
  70.  
  71. /* Call of the File Requester */
  72.  
  73. struct IntuiText text_na;
  74. struct IntuiText text_aha;
  75.  
  76. static char def_name[REQ_FCHARS]="";
  77. static char def_dir[REQ_DSIZE]="";
  78. static char str_filenam[REQ_FCHARS+REQ_DSIZE]="";
  79.  
  80. USHORT filerequest(char *titel,char *str_filenam)
  81. { struct Process *OurTask;
  82.   struct Window    *old_pr_WindowPtr;
  83.   struct FileReq freq;
  84.  
  85.   OurTask = (struct Process *)FindTask((char *)0L);
  86.   old_pr_WindowPtr = OurTask->pr_WindowPtr;
  87.   OurTask->pr_WindowPtr = win;
  88.   
  89.   memset(&freq,0,sizeof(freq));
  90.   str_filenam[0]=0;
  91.   freq.Title=titel;
  92.   freq.PathName=str_filenam;
  93.   freq.Dir=def_dir;
  94.   freq.File=def_name;
  95.   if (FileRequester(&freq))
  96.   { OurTask->pr_WindowPtr = old_pr_WindowPtr;
  97.     return(1);
  98.   }
  99.   else
  100.   {
  101.     OurTask->pr_WindowPtr = old_pr_WindowPtr;
  102.     return(0);
  103.   }
  104.  
  105. void MessReq(UBYTE *string)
  106. { struct Process *OurTask;
  107.   struct Window    *old_pr_WindowPtr;
  108.   struct TRStructure tr;
  109.  
  110.   OurTask = (struct Process *)FindTask((char *)0L);
  111.   old_pr_WindowPtr = OurTask->pr_WindowPtr;
  112.   OurTask->pr_WindowPtr = win;
  113.   memset(&tr,0,sizeof(tr));
  114.   tr.Text=string;
  115.   tr.Title="Program Message";
  116.   TextRequest(&tr);
  117.   OurTask->pr_WindowPtr = old_pr_WindowPtr;
  118. }
  119.  
  120. void NotAvailable()
  121. {  MessReq((UBYTE *)"Funktion not available!");
  122. }
  123.  
  124. UBYTE DoScsi(UBYTE *cmd, UWORD cmdlen, UWORD *data, ULONG datalen, UBYTE flags)
  125. { struct SCSICmd scmd;
  126.   scmd.scsi_Command=cmd;
  127.   scmd.scsi_CmdLength=cmdlen;
  128.   scmd.scsi_Data=data;
  129.   scmd.scsi_Length=datalen;
  130.   scmd.scsi_Flags=flags;
  131.   diskreq->io_Length = sizeof(struct SCSICmd);
  132.   diskreq->io_Data = &scmd;
  133.   diskreq->io_Command = 28;
  134.   DoIO(diskreq);
  135.   return(scmd.scsi_Status);
  136. }
  137.  
  138.  
  139. void inquiry()
  140. { UBYTE string[96],inq_txt[45];
  141.  
  142.   DoScsi(&cmd_inqu,6,(UWORD *)&string,96,DIR_READ);
  143.   strncpy(&inq_txt[0],&string[8],39);
  144.   MessReq(&inq_txt[0]);
  145. }
  146.  
  147. void scan()
  148. { ULONG memsize,memadd,blsize;
  149.   short tabindex,blocks,rest,i,glin,rlin;
  150.   UBYTE *rdptr;
  151.  
  152.   if (memptr) free(memptr);
  153.   memneed=0;
  154.   tabindex=((winpar.resx/100)-2)+(winpar.size-4)*3;
  155.   winpar.cornerx=cornerxval[tabindex];
  156.   winpar.cornery=corneryval[tabindex];
  157.   winpar.width=widthval[tabindex];
  158.   winpar.height=heightval[tabindex];
  159.   memsize=(winpar.halftone)?((ULONG)winpar.width*(ULONG)winpar.height)>>1:
  160.                             ((ULONG)winpar.width*(ULONG)winpar.height)>>3;
  161.   memadd=(memgray)?((ULONG)memwidth*ADDLIN)>>1:
  162.                    ((ULONG)memwidth*ADDLIN)>>3;
  163.   if ((memptr=(UBYTE*)malloc(memsize+memadd))==NULL)
  164.     MessReq((UBYTE*)"Out of Memmory!");
  165.   else 
  166.   { memneed=memsize;
  167.     memwidth=winpar.width;
  168.     memheight=winpar.height;
  169.     memgray=winpar.halftone;
  170.     rdptr=memptr;
  171.     if (!(winpar.halftone))
  172.     { DoScsi(&cmd_mdon,6,NULL,0,0);
  173.       Delay(100);
  174.       DoScsi(&cmd_dwin,10,&winpar,40,DIR_WRITE);
  175.       DoScsi(&cmd_scan,6,NULL,0,0);
  176.       blocks=memsize/0x8000;
  177.       rest=memsize%0x8000;
  178.       cmd_read[7]=128; cmd_read[8]=0;
  179.       for (i=0;i<blocks;i++) 
  180.       { DoScsi(&cmd_read,10,rdptr,0x8000,DIR_READ);
  181.         rdptr+=0x8000;
  182.       }
  183.       cmd_read[7]=(rest>>8)&0xff; cmd_read[8]=rest&0xff;
  184.       DoScsi(&cmd_read,10,rdptr,rest,DIR_READ);
  185.       rdptr+=rest;
  186.     }
  187.     else
  188.     { glin=winpar.height;
  189.       rlin=0x200000L/(ULONG)winpar.width; 
  190.       do 
  191.       { if (rlin>glin) rlin=glin;
  192.         winpar.height=rlin;
  193.         glin-=rlin;
  194.         DoScsi(&cmd_mdon,6,NULL,0,0);
  195.         Delay(100);
  196.         DoScsi(&cmd_dwin,10,&winpar,40,DIR_WRITE);
  197.         DoScsi(&cmd_scan,6,NULL,0,0);
  198.     winpar.cornery+=rlin;
  199.         blsize=((ULONG)winpar.height*(ULONG)winpar.width)>>1;
  200.         blocks=blsize/0x4000;
  201.         rest=blsize%0x4000;
  202.         cmd_read[7]=128; cmd_read[8]=0;
  203.         for (i=0;i<blocks;i++) 
  204.         { DoScsi(&cmd_read,10,rdptr,0x8000,DIR_READ);
  205.           p64to16(rdptr,0x4000);
  206.           rdptr+=0x4000;
  207.         }
  208.         cmd_read[7]=(rest>>7)&0xff; cmd_read[8]=(rest<<1)&0xff;
  209.         DoScsi(&cmd_read,10,rdptr,rest<<1,DIR_READ);
  210.         p64to16(rdptr,rest);
  211.     rdptr+=rest;
  212.       } while (glin);
  213.     }
  214.     DoScsi(&cmd_mdoff,6,NULL,0,0); 
  215.   }
  216. }  
  217.     
  218.  
  219. static ULONG cmpline(UBYTE *zeile, UWORD len, UWORD pnum, FILE *qdatei)
  220. { ULONG count;
  221.   UWORD plen,p;
  222.   UBYTE m;
  223.   WORD i,j;
  224.   static UBYTE cplane[6000];
  225.  
  226.   count=0;
  227.   plen=len/pnum;
  228.   for (p=0;p<pnum;p++)
  229.   { i=0;
  230.     while(i<plen)
  231.     { m=(*(zeile+i));
  232.       for (j=i+1;((m==(*(zeile+j)))&&(j<plen)&&(j<(i+125)));j++);
  233.       if (j!=(i+1))
  234.       { cplane[count++]=(UBYTE)((257-j+i)&0xff);
  235.         cplane[count++]=m;
  236.         i=j;
  237.       }
  238.       else
  239.       { for (;(m!=(*(zeile+j))&&(j<=plen)&&(j<(i+125)));m=(*(zeile+(j++))));
  240.         if (j<plen) j-=2;
  241.         j=((plen-1)<j)?(plen-1):j;
  242.         cplane[count++]=(UBYTE)(j-i);
  243.         for(;i<=j;cplane[count++]=(*(zeile+(i++))));
  244.       }
  245.     }
  246.     zeile+=plen;
  247.   }
  248.   fwrite(&cplane[0],count,1,qdatei);
  249.   return(count);
  250. }
  251.  
  252.  
  253. void load()
  254. { FILE *sdatei;
  255.   ULONG memsize,memadd;
  256.   UWORD i,j,t;
  257.   UBYTE *loadptr;
  258.   UBYTE planes[4000];
  259.   UBYTE b,cflag,rflag,cnt,cval;
  260.   UWORD bflag=1;
  261.  
  262.   if (filerequest("Load IFF File",str_filenam))
  263.   { sdatei=fopen(str_filenam,"rb");
  264.     fread(&iffheader,sizeof(iffheader),1,sdatei);
  265.     if ((iffheader.iff_magic!=FORM)||(iffheader.ilbm_magic!=ILBM)||
  266.         (iffheader.bmhd_magic!=BMHD)||(iffheader.bmhd_len!=20))
  267.     { MessReq("No IFF-ILBM File!");
  268.       fclose(sdatei);
  269.     }
  270.     else
  271.     { if (memptr) free(memptr);
  272.       memneed=0;
  273.       memgray=((iffheader.d)!=1);
  274.       memwidth=iffheader.w;
  275.       memheight=iffheader.h;
  276.       memsize=(memgray)?((ULONG)memwidth*(ULONG)memheight)>>1:
  277.                         ((ULONG)memwidth*(ULONG)memheight)>>3;
  278.       memadd=(memgray)?((ULONG)memwidth*ADDLIN)>>1:
  279.                        ((ULONG)memwidth*ADDLIN)>>3;
  280.       if ((memptr=(UBYTE*)malloc(memsize+memadd))==NULL)
  281.       { MessReq((UBYTE*)"Out of Memmory!");
  282.         fclose(sdatei);
  283.       }
  284.       else
  285.       { memneed=memsize;
  286.         while (bflag) /* hier CMAP und Body suchen */
  287.         { fread(&chunk_hd[0],8,1,sdatei);
  288.           if (chunk_hd[0]==BODY) bflag=0;
  289.           else fseek(sdatei,chunk_hd[1],SEEK_CUR);
  290.         }
  291.         if (memgray)
  292.         { loadptr=memptr;
  293.           memset(&planes[0],0,4000);
  294.           if (iffheader.cmp) for (i=0;i<memheight;i++)
  295.           { t=0;
  296.             while (t<iffheader.d*(memwidth<<3))
  297.             { fread(&cnt,1,1,sdatei);
  298.               if (cnt>128)
  299.               { fread(&cval,1,1,sdatei);
  300.                 for (i=0;i<(257-cnt);i++) planes[t++]=cval;
  301.               }
  302.               if (cnt<128)
  303.               { fread(&planes[t],++cnt,1,sdatei);
  304.                 t+=cnt;
  305.               }
  306.             }
  307.             fplanegen(loadptr,&planes[0],&planes[memwidth>>3],
  308.                       &planes[2*(memwidth>>3)],&planes[3*(memwidth>>3)],(memwidth>>3));
  309.             loadptr+=(memwidth>>1);
  310.           }
  311.           else for (i=0;i<memheight;i++)
  312.           { fread(&planes[0],iffheader.d*(memwidth>>3),1,sdatei);
  313.             fplanegen(loadptr,&planes[0],&planes[memwidth>>3],
  314.                       &planes[2*(memwidth>>3)],&planes[3*(memwidth>>3)],(memwidth>>3));
  315.             loadptr+=(memwidth>>1);
  316.           }
  317.         }
  318.         else
  319.         { if (iffheader.cmp)
  320.           { loadptr=memptr;
  321.             while ((fread(&cnt,1,1,sdatei)))
  322.             { if (cnt>128)
  323.               { fread(&cval,1,1,sdatei);
  324.                 for (i=0;i<(257-cnt);i++) *(loadptr++)=cval;
  325.               }
  326.               if (cnt<128)
  327.               { fread(loadptr,++cnt,1,sdatei);
  328.                 loadptr+=cnt;
  329.               }
  330.             }
  331.           }
  332.           else fread(memptr,(iffheader.w>>3)*iffheader.h,1,sdatei);
  333.         }
  334.         fclose(sdatei);
  335.       }
  336.     }
  337.   }
  338. }
  339.  
  340. void save(UWORD wx1,UWORD wy1,UWORD wx2,UWORD wy2,UBYTE cmp,UBYTE mf)
  341. { FILE *qdatei;
  342.   ULONG totlen,bmlen;
  343.   UWORD width,height,i,t;
  344.   ULONG startofs,cmplen;
  345.   UBYTE *saveptr;
  346.   UBYTE planes[4000];
  347.   UBYTE sf;
  348.   UBYTE dummy=0;
  349.  
  350.   if (filerequest("Save IFF File",str_filenam))
  351.   { sf=(memgray)?1:3;
  352.     if (mf==2)
  353.     { if (wx1>wx2) {t=wx2; wx2=wx1; wx1=t;}
  354.       if (wy1>wy2) {t=wy2; wy2=wy1; wy1=t;}
  355.       width=(wx2-wx1);
  356.       height=(wy2-wy1);
  357.       startofs=wy1*(memwidth>>sf)+(wx1>>sf);
  358.     }
  359.     else 
  360.     { width=memwidth;
  361.       height=memheight;
  362.       startofs=0;
  363.     }
  364.     width&=0xfff0;
  365.     qdatei=fopen(str_filenam,"wb");
  366.     bmlen=(memgray)?((width>>1)*height):((width>>3)*height);
  367.     totlen=bmlen+40+((memgray)?56:14);
  368.     iff_head[1]=totlen; 
  369.     iff_head[5]=(width<<16)|height;
  370.     iff_head[7]=((memgray)?0x04000000:0x01000000)|((cmp)?0x0100:0);
  371.     iff_body[1]=bmlen;
  372.     fwrite(&iff_head[0],sizeof(iff_head),1,qdatei);
  373.     if (memgray) fwrite(iff_cmap_gray,sizeof(iff_cmap_gray),1,qdatei);
  374.     else fwrite(iff_cmap_bw,sizeof(iff_cmap_bw),1,qdatei);
  375.     fwrite(iff_body,sizeof(iff_body),1,qdatei);
  376.     saveptr=memptr+startofs;
  377.     cmplen=0;
  378.     if (memgray) for (i=0;i<height;i++)
  379.     { fplanesep(saveptr,&planes[0],&planes[width>>3],&planes[2*(width>>3)],&planes[3*(width>>3)],(width>>3));
  380.       if (cmp) cmplen+=cmpline(&planes[0],width>>1,4,qdatei);
  381.       else fwrite(&planes[0],width>>1,1,qdatei);
  382.       saveptr+=(ULONG)(memwidth>>1);
  383.     }
  384.     else for (i=0;i<height;i++)
  385.     { if (cmp) cmplen+=cmpline(saveptr,width>>3,1,qdatei);
  386.       else fwrite(saveptr,width>>3,1,qdatei);
  387.       saveptr+=(ULONG)(memwidth>>3);
  388.     }
  389.     if (cmp)
  390.     { if (cmplen&1) fwrite(&dummy,1,1,qdatei);
  391.       fseek(qdatei,sizeof(iff_head)+((memgray)?(sizeof(iff_cmap_gray)):
  392.             (sizeof(iff_cmap_bw)))+4,SEEK_SET);
  393.       fwrite(&cmplen,4,1,qdatei);
  394.       if (cmplen&1) cmplen++;
  395.       fseek(qdatei,4,SEEK_SET);
  396.       cmplen+=((memgray)?96:54);
  397.       fwrite(&cmplen,4,1,qdatei);
  398.     }
  399.     fclose(qdatei); 
  400.   }
  401. }
  402.  
  403. void view(UWORD x, UWORD y, UBYTE zoom)
  404. { UBYTE *vptr;
  405.   UBYTE *plptr[4];
  406.   ULONG vinc;
  407.   ULONG vicr[13];
  408.   UWORD i,j,k,n1,n2,zeile;
  409.   UBYTE linebuf[1000];
  410.  
  411.   for (i=0;i<4;i++) plptr[i]=(UBYTE *)(rp->BitMap->Planes[i]+1680);
  412.   vptr=(memgray)?
  413.        (UBYTE*)(memptr+(((memwidth>>1)*y)+(x>>1))):
  414.        (UBYTE*)(memptr+(((memwidth>>3)*y)+(x>>3)));
  415.   vinc=(memgray)?(ULONG)(memwidth>>1):(ULONG)(memwidth>>3);
  416.   if (zoom)
  417.   { if ((memheight/4)<VIEWHEIGHT) sk=4;
  418.     else if ((memheight/8)<VIEWHEIGHT) sk=8;
  419.     else if ((memheight/12)<VIEWHEIGHT) sk=12;
  420.     vptr=memptr;
  421.     vicr[0]=0; vicr[1]=vinc;
  422.     for (i=2;i<13;i++) vicr[i]=vicr[i-1]+vinc;
  423.     clrscr(plptr[0],plptr[1],plptr[2],plptr[3]);
  424.     zeile=0; vx=vy=0;
  425.     if (memgray)
  426.     switch (sk)
  427.     { case 4: while(zeile<memheight)
  428.               { zeile+=4;
  429.                 for (i=0;i<(memwidth>>1);i+=4)
  430.                 { n1=n2=0; j=i;
  431.                   for (k=0;k<4;k++)
  432.                   { n1+=((*(vptr+j  )>>4)+(*(vptr+j  )&15)+(*(vptr+j+1)>>4)+(*(vptr+j+1)&15));
  433.                     n2+=((*(vptr+j+2)>>4)+(*(vptr+j+2)&15)+(*(vptr+j+3)>>4)+(*(vptr+j+3)&15));
  434.                     j+=vinc;
  435.                   }
  436.                   linebuf[i>>2]=(n1&0xf0)|(n2>>4);
  437.                 }
  438.                 vplanesep(&linebuf[0],plptr[0],plptr[1],plptr[2],plptr[3],memwidth>>5);
  439.                 plptr[0]+=80; plptr[1]+=80; plptr[2]+=80; plptr[3]+=80;
  440.                 vptr+=vicr[4];
  441.               } 
  442.               break;
  443.       case 8: while(zeile<memheight)
  444.               { zeile+=8;
  445.                 for (i=0;i<(memwidth>>1);i+=8)
  446.                 { n1=n2=0; j=i;
  447.                   for (k=0;k<8;k++)
  448.                   { n1+=((*(vptr+j  )>>4)+(*(vptr+j  )&15)+(*(vptr+j+1)>>4)+(*(vptr+j+1)&15)
  449.                         +(*(vptr+j+2)>>4)+(*(vptr+j+2)&15)+(*(vptr+j+3)>>4)+(*(vptr+j+3)&15));
  450.                     n2+=((*(vptr+j+4)>>4)+(*(vptr+j+4)&15)+(*(vptr+j+5)>>4)+(*(vptr+j+5)&15)
  451.                         +(*(vptr+j+6)>>4)+(*(vptr+j+6)&15)+(*(vptr+j+7)>>4)+(*(vptr+j+7)&15));
  452.                     j+=vinc;
  453.                   }
  454.                   linebuf[i>>3]=((n1>>2)&0xf0)|((n2>>6)&0x0f);
  455.                 }
  456.                 vplanesep(&linebuf[0],plptr[0],plptr[1],plptr[2],plptr[3],memwidth>>6);
  457.                 plptr[0]+=80; plptr[1]+=80; plptr[2]+=80; plptr[3]+=80;
  458.                 vptr+=vicr[8];
  459.               } 
  460.               break;
  461.       case 12:while(zeile<memheight)
  462.               { zeile+=12;
  463.                 for (i=0;i<(memwidth>>1);i+=12)
  464.                 { n1=n2=0; j=i;
  465.                   for (k=0;k<12;k++)
  466.                   { n1+=((*(vptr+j   )>>4)+(*(vptr+j   )&15)+(*(vptr+j+ 1)>>4)+(*(vptr+j+ 1)&15)
  467.                         +(*(vptr+j+ 2)>>4)+(*(vptr+j+ 2)&15)+(*(vptr+j+ 3)>>4)+(*(vptr+j+ 3)&15)
  468.                         +(*(vptr+j+ 4)>>4)+(*(vptr+j+ 4)&15)+(*(vptr+j+ 5)>>4)+(*(vptr+j+ 5)&15));
  469.                     n2+=((*(vptr+j+ 6)>>4)+(*(vptr+j+ 6)&15)+(*(vptr+j+ 7)>>4)+(*(vptr+j+ 7)&15)
  470.                         +(*(vptr+j+ 8)>>4)+(*(vptr+j+ 8)&15)+(*(vptr+j+ 9)>>4)+(*(vptr+j+ 9)&15)
  471.                         +(*(vptr+j+10)>>4)+(*(vptr+j+10)&15)+(*(vptr+j+11)>>4)+(*(vptr+j+11)&15));
  472.                     j+=vinc;
  473.                   }
  474.                   linebuf[i/12]=(((n1/144)<<4)&0xf0)|((n2/144)&0x0f);
  475.                 }
  476.                 vplanesep(&linebuf[0],plptr[0],plptr[1],plptr[2],plptr[3],memwidth/96);
  477.                 plptr[0]+=80; plptr[1]+=80; plptr[2]+=80; plptr[3]+=80;
  478.                 vptr+=vicr[12];
  479.               } 
  480.               break;
  481.     }
  482.     else
  483.     switch (sk)
  484.     { case 4: while(zeile<memheight)
  485.               { zeile+=4;
  486.                 for (i=0;i<(memwidth>>3);i++)
  487.                 { n1=numbits[(*(vptr+i        ))>>4]+numbits[(*(vptr+i+vicr[1]))>>4]
  488.                     +numbits[(*(vptr+i+vicr[2]))>>4]+numbits[(*(vptr+i+vicr[3]))>>4];
  489.                   if (n1==16) n1=15;
  490.                   n2=numbits[(*(vptr+i        ))&15]+numbits[(*(vptr+i+vicr[1]))&15]
  491.                     +numbits[(*(vptr+i+vicr[2]))&15]+numbits[(*(vptr+i+vicr[3]))&15];
  492.                   if (n2==16) n2=15;
  493.                   linebuf[i]=(~((n1<<4)|n2));
  494.                 }
  495.                 vplanesep(&linebuf[0],plptr[0],plptr[1],plptr[2],plptr[3],memwidth>>5);
  496.                 plptr[0]+=80; plptr[1]+=80; plptr[2]+=80; plptr[3]+=80;
  497.                 vptr+=vicr[4];
  498.               } 
  499.               break;
  500.       case 8: while(zeile<memheight)
  501.               { zeile+=8;
  502.                 for (i=0;i<(memwidth>>3);i+=2)
  503.                 { n1=(numbits[(*(vptr+i        ))]
  504.                      +numbits[(*(vptr+i+vicr[1]))]
  505.                      +numbits[(*(vptr+i+vicr[2]))]
  506.                      +numbits[(*(vptr+i+vicr[3]))]
  507.                      +numbits[(*(vptr+i+vicr[4]))]
  508.                      +numbits[(*(vptr+i+vicr[5]))]
  509.                      +numbits[(*(vptr+i+vicr[6]))]
  510.                      +numbits[(*(vptr+i+vicr[7]))])>>2;
  511.                   if (n1==16) n1=15;
  512.                   n2=(numbits[(*(vptr+i+1        ))]
  513.                      +numbits[(*(vptr+i+1+vicr[1]))]
  514.                      +numbits[(*(vptr+i+1+vicr[2]))]
  515.                      +numbits[(*(vptr+i+1+vicr[3]))]
  516.                      +numbits[(*(vptr+i+1+vicr[4]))]
  517.                      +numbits[(*(vptr+i+1+vicr[5]))]
  518.                      +numbits[(*(vptr+i+1+vicr[6]))]
  519.                      +numbits[(*(vptr+i+1+vicr[7]))])>>2;
  520.                   if (n2==16) n2=15;
  521.                   linebuf[i>>1]=(~((n1<<4)|n2));
  522.                 }
  523.                 vplanesep(&linebuf[0],plptr[0],plptr[1],plptr[2],plptr[3],memwidth>>6);
  524.                 plptr[0]+=80; plptr[1]+=80; plptr[2]+=80; plptr[3]+=80;
  525.                 vptr+=vicr[8];
  526.               } 
  527.               break;
  528.       case 12:while(zeile<memheight)
  529.               { zeile+=12;
  530.                 for (i=0;i<(memwidth>>3);i+=3)
  531.                 { n1=(numbits[(*(vptr+i           ))]
  532.                      +numbits[(*(vptr+i+  vicr[ 1]))]
  533.                      +numbits[(*(vptr+i+  vicr[ 2]))]
  534.                      +numbits[(*(vptr+i+  vicr[ 3]))]
  535.                      +numbits[(*(vptr+i+  vicr[ 4]))]
  536.                      +numbits[(*(vptr+i+  vicr[ 5]))]
  537.                      +numbits[(*(vptr+i+  vicr[ 6]))]
  538.                      +numbits[(*(vptr+i+  vicr[ 7]))]
  539.                      +numbits[(*(vptr+i+  vicr[ 8]))]
  540.                      +numbits[(*(vptr+i+  vicr[ 9]))]
  541.                      +numbits[(*(vptr+i+  vicr[10]))]
  542.                      +numbits[(*(vptr+i+  vicr[11]))]
  543.                      +numbits[(*(vptr+i+1         ))>>4]
  544.                      +numbits[(*(vptr+i+1+vicr[ 1]))>>4]
  545.                      +numbits[(*(vptr+i+1+vicr[ 2]))>>4]
  546.                      +numbits[(*(vptr+i+1+vicr[ 3]))>>4]
  547.                      +numbits[(*(vptr+i+1+vicr[ 4]))>>4]
  548.                      +numbits[(*(vptr+i+1+vicr[ 5]))>>4]
  549.                      +numbits[(*(vptr+i+1+vicr[ 6]))>>4]
  550.                      +numbits[(*(vptr+i+1+vicr[ 7]))>>4]
  551.                      +numbits[(*(vptr+i+1+vicr[ 8]))>>4]
  552.                      +numbits[(*(vptr+i+1+vicr[ 9]))>>4]
  553.                      +numbits[(*(vptr+i+1+vicr[10]))>>4]
  554.                      +numbits[(*(vptr+i+1+vicr[11]))>>4]);
  555.                   n2=(numbits[(*(vptr+i+2         ))]
  556.                      +numbits[(*(vptr+i+2+vicr[ 1]))]
  557.                      +numbits[(*(vptr+i+2+vicr[ 2]))]
  558.                      +numbits[(*(vptr+i+2+vicr[ 3]))]
  559.                      +numbits[(*(vptr+i+2+vicr[ 4]))]
  560.                      +numbits[(*(vptr+i+2+vicr[ 5]))]
  561.                      +numbits[(*(vptr+i+2+vicr[ 6]))]
  562.                      +numbits[(*(vptr+i+2+vicr[ 7]))]
  563.                      +numbits[(*(vptr+i+2+vicr[ 8]))]
  564.                      +numbits[(*(vptr+i+2+vicr[ 9]))]
  565.                      +numbits[(*(vptr+i+2+vicr[10]))]
  566.                      +numbits[(*(vptr+i+2+vicr[11]))]
  567.                      +numbits[(*(vptr+i+1         ))&15]
  568.                      +numbits[(*(vptr+i+1+vicr[ 1]))&15]
  569.                      +numbits[(*(vptr+i+1+vicr[ 2]))&15]
  570.                      +numbits[(*(vptr+i+1+vicr[ 3]))&15]
  571.                      +numbits[(*(vptr+i+1+vicr[ 4]))&15]
  572.                      +numbits[(*(vptr+i+1+vicr[ 5]))&15]
  573.                      +numbits[(*(vptr+i+1+vicr[ 6]))&15]
  574.                      +numbits[(*(vptr+i+1+vicr[ 7]))&15]
  575.                      +numbits[(*(vptr+i+1+vicr[ 8]))&15]
  576.                      +numbits[(*(vptr+i+1+vicr[ 9]))&15]
  577.                      +numbits[(*(vptr+i+1+vicr[10]))&15]
  578.                      +numbits[(*(vptr+i+1+vicr[11]))&15]);
  579.                   n1=n1/9;
  580.                   n2=n2/9;
  581.                   if (n1==16) n1=15;
  582.                   if (n2==16) n2=15;
  583.                   linebuf[i/3]=(~((n1<<4)|n2));
  584.                 }
  585.                 vplanesep(&linebuf[0],plptr[0],plptr[1],plptr[2],plptr[3],memwidth/96);
  586.                 plptr[0]+=80; plptr[1]+=80; plptr[2]+=80; plptr[3]+=80;
  587.                 vptr+=vicr[12];
  588.               } 
  589.               break;
  590.     }    
  591.   }
  592.   else
  593.   { vx=x&0xfff0; vy=y&0xfffe; sk=1;
  594.     if (memgray) grayview(vptr,plptr[0],plptr[1],plptr[2],plptr[3],vinc); 
  595.     else bwview(vptr,plptr[0],plptr[1],plptr[2],plptr[3],vinc); 
  596.   } 
  597. }
  598.  
  599. UWORD s2px(UWORD x)
  600. { int t;
  601.   t=x*sk+vx;
  602.   if (t>=memwidth) t=memwidth-1;
  603.   if (t<0) t=0;
  604.   return((UWORD)t);
  605. }
  606.  
  607. UWORD s2py(UWORD y)
  608. { int t;
  609.   t=y*sk+vy;
  610.   if (t>=memheight) t=memheight-1;
  611.   if (t<0) t=0;
  612.   return((UWORD)t);
  613. }
  614.  
  615. UWORD p2sx(UWORD x)
  616. { int t;
  617.   t=(x-vx)/sk;
  618.   if (t>623) t=623;
  619.   if (t<0) t=0;
  620.   return((UWORD)t);
  621. }
  622.  
  623. UWORD p2sy(UWORD y)
  624. { int t;
  625.   t=(y-vy)/sk;
  626.   if (t>(VIEWHEIGHT-1)) t=VIEWHEIGHT-1;
  627.   if (t<0) t=0;
  628.   return((UWORD)t);
  629. }
  630.  
  631. void drawbox(UWORD wx1,UWORD wy1,UWORD wx2,UWORD wy2,struct RastPort *wrp)
  632. { UWORD sx1,sy1,sx2,sy2;
  633.   
  634.   sx1=p2sx(wx1); sy1=p2sy(wy1)+11;
  635.   sx2=p2sx(wx2); sy2=p2sy(wy2)+11; 
  636.   SetWrMsk(wrp,8);
  637.   SetAPen(wrp,8);
  638.   SetDrMd(wrp,COMPLEMENT|JAM1);
  639.   SetDrPt(wrp,0xcccc);
  640.   Move(wrp,sx1,sy1);
  641.   Draw(wrp,sx1,sy2);
  642.   Draw(wrp,sx2,sy2);
  643.   Draw(wrp,sx2,sy1);
  644.   Draw(wrp,sx1,sy1);
  645.   SetWrMsk(wrp,1);
  646.   SetAPen(wrp,1);
  647.   SetDrMd(wrp,COMPLEMENT|JAM1);
  648.   SetDrPt(wrp,0x3333);
  649.   Move(wrp,sx1,sy1);
  650.   Draw(wrp,sx1,sy2);
  651.   Draw(wrp,sx2,sy2);
  652.   Draw(wrp,sx2,sy1);
  653.   Draw(wrp,sx1,sy1);
  654.   SetWrMsk(wrp,15);
  655. }
  656.  
  657. void cut(UWORD wx1,UWORD wy1,UWORD wx2,UWORD wy2,UBYTE mf)
  658. { UWORD width,height,x,y,t;
  659.   ULONG startofs;
  660.   UBYTE *picptr,*cpyptr;
  661.   UBYTE sf;
  662.  
  663.   sf=(memgray)?1:3;
  664.   if ((memwidth<=640)||(memheight<=512)) MessReq("Area already has minimal size");
  665.   if (mf!=2) MessReq("No Area selected!");
  666.   else
  667.   { if (wx1>wx2) {t=wx2; wx2=wx1; wx1=t;}
  668.     if (wy1>wy2) {t=wy2; wy2=wy1; wy1=t;}
  669.     width=(wx2-wx1);
  670.     height=(wy2-wy1);
  671.     if (height<512) 
  672.     { height=512;
  673.       if ((wy1+height)>memheight) wy1=memheight-height;
  674.     }
  675.     if (width<640) 
  676.     { width=640;
  677.       if ((wx1+width)>memwidth) wx1=memwidth-width;
  678.     }
  679.     startofs=wy1*(memwidth>>sf)+(wx1>>sf);
  680.     picptr=memptr;
  681.     for (y=0;y<height;y++)
  682.     { cpyptr=memptr+startofs;
  683.       for(x=0;x<(width>>sf);x++) *(picptr++)=*(cpyptr++);
  684.       startofs+=(ULONG)(memwidth>>sf);
  685.     }
  686.     mf=0;
  687.     memwidth=width;
  688.     memheight=height;
  689.     if (!(memptr=(UBYTE *)realloc(memptr,(memwidth*(memheight+ADDLIN))>>sf)))
  690.     { memneed=0;
  691.       MessReq((UBYTE *)"Out Of Memory!");
  692.     }
  693.   }
  694. }
  695.