/* imginout.c input/output routines for stscan.c */ #include #include #include #include #include #include #include #include #include #include #include #include #include "stscan.h" #define ST400LUN 96 #define DEV_NAME (char*)"scsi.device" /* <- change for other SCSI controller */ #define FORM 0x464f524d #define ILBM 0x494c424d #define BMHD 0x424d4844 #define BODY 0x424f4459 #define DIR_READ 1 #define DIR_WRITE 0 /* Scanner specific sizes and commands */ static UWORD cornerxval[]={ 22, 33, 44, 266, 399, 535}; static UWORD corneryval[]={ 6, 6, 6, 6, 6, 6}; static UWORD widthval[]= {1664,2496,3312,1168,1760,2336}; static UWORD heightval[]= {2336,3504,4672,1656,2484,3312}; static UBYTE cmd_scan[]={0x1b,ST400LUN,0,0,0,0}; static UBYTE cmd_read[]={0x28,ST400LUN,0,0,0,0,0,0,0,0}; static UBYTE cmd_dwin[]={0x24,ST400LUN,0,0,0,0,0,0,40,0}; static UBYTE cmd_mdon[]={0x15,ST400LUN,0,0,0,128}; static UBYTE cmd_mdoff[]={0x15,ST400LUN,0,0,0,0}; static UBYTE cmd_inqu[]={0x12,ST400LUN,0,0,96,0}; /* IFF-ILBM Constants */ static UBYTE iff_cmap_bw[]= {'C','M','A','P',0,0,0,6,0,0,0,255,255,255}; static UBYTE iff_cmap_gray[]= {'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, 96,96,96,112,112,112,128,128,128,144,144,144,160,160,160,176,176,176, 192,192,192,208,208,208,224,224,224,240,240,240}; static ULONG iff_head[]={FORM,0,ILBM,BMHD,20,0,0,0,0x00000101,0x02800200}; static ULONG iff_body[]={BODY,0}; static ULONG chunk_hd[2]; typedef struct iffhead { ULONG iff_magic; ULONG filelen; ULONG ilbm_magic; ULONG bmhd_magic; ULONG bmhd_len; UWORD w,h,x,y; UBYTE d, mask, cmp, pad; UWORD transparent,aspect,pw,ph; }; static struct iffhead iffheader; UBYTE sk; UWORD vx,vy; /* Call of the File Requester */ struct IntuiText text_na; struct IntuiText text_aha; static char def_name[REQ_FCHARS]=""; static char def_dir[REQ_DSIZE]=""; static char str_filenam[REQ_FCHARS+REQ_DSIZE]=""; USHORT filerequest(char *titel,char *str_filenam) { struct Process *OurTask; struct Window *old_pr_WindowPtr; struct FileReq freq; OurTask = (struct Process *)FindTask((char *)0L); old_pr_WindowPtr = OurTask->pr_WindowPtr; OurTask->pr_WindowPtr = win; memset(&freq,0,sizeof(freq)); str_filenam[0]=0; freq.Title=titel; freq.PathName=str_filenam; freq.Dir=def_dir; freq.File=def_name; if (FileRequester(&freq)) { OurTask->pr_WindowPtr = old_pr_WindowPtr; return(1); } else { OurTask->pr_WindowPtr = old_pr_WindowPtr; return(0); } } void MessReq(UBYTE *string) { struct Process *OurTask; struct Window *old_pr_WindowPtr; struct TRStructure tr; OurTask = (struct Process *)FindTask((char *)0L); old_pr_WindowPtr = OurTask->pr_WindowPtr; OurTask->pr_WindowPtr = win; memset(&tr,0,sizeof(tr)); tr.Text=string; tr.Title="Program Message"; TextRequest(&tr); OurTask->pr_WindowPtr = old_pr_WindowPtr; } void NotAvailable() { MessReq((UBYTE *)"Funktion not available!"); } UBYTE DoScsi(UBYTE *cmd, UWORD cmdlen, UWORD *data, ULONG datalen, UBYTE flags) { struct SCSICmd scmd; scmd.scsi_Command=cmd; scmd.scsi_CmdLength=cmdlen; scmd.scsi_Data=data; scmd.scsi_Length=datalen; scmd.scsi_Flags=flags; diskreq->io_Length = sizeof(struct SCSICmd); diskreq->io_Data = &scmd; diskreq->io_Command = 28; DoIO(diskreq); return(scmd.scsi_Status); } void inquiry() { UBYTE string[96],inq_txt[45]; DoScsi(&cmd_inqu,6,(UWORD *)&string,96,DIR_READ); strncpy(&inq_txt[0],&string[8],39); MessReq(&inq_txt[0]); } void scan() { ULONG memsize,memadd,blsize; short tabindex,blocks,rest,i,glin,rlin; UBYTE *rdptr; if (memptr) free(memptr); memneed=0; tabindex=((winpar.resx/100)-2)+(winpar.size-4)*3; winpar.cornerx=cornerxval[tabindex]; winpar.cornery=corneryval[tabindex]; winpar.width=widthval[tabindex]; winpar.height=heightval[tabindex]; memsize=(winpar.halftone)?((ULONG)winpar.width*(ULONG)winpar.height)>>1: ((ULONG)winpar.width*(ULONG)winpar.height)>>3; memadd=(memgray)?((ULONG)memwidth*ADDLIN)>>1: ((ULONG)memwidth*ADDLIN)>>3; if ((memptr=(UBYTE*)malloc(memsize+memadd))==NULL) MessReq((UBYTE*)"Out of Memmory!"); else { memneed=memsize; memwidth=winpar.width; memheight=winpar.height; memgray=winpar.halftone; rdptr=memptr; if (!(winpar.halftone)) { DoScsi(&cmd_mdon,6,NULL,0,0); Delay(100); DoScsi(&cmd_dwin,10,&winpar,40,DIR_WRITE); DoScsi(&cmd_scan,6,NULL,0,0); blocks=memsize/0x8000; rest=memsize%0x8000; cmd_read[7]=128; cmd_read[8]=0; for (i=0;i>8)&0xff; cmd_read[8]=rest&0xff; DoScsi(&cmd_read,10,rdptr,rest,DIR_READ); rdptr+=rest; } else { glin=winpar.height; rlin=0x200000L/(ULONG)winpar.width; do { if (rlin>glin) rlin=glin; winpar.height=rlin; glin-=rlin; DoScsi(&cmd_mdon,6,NULL,0,0); Delay(100); DoScsi(&cmd_dwin,10,&winpar,40,DIR_WRITE); DoScsi(&cmd_scan,6,NULL,0,0); winpar.cornery+=rlin; blsize=((ULONG)winpar.height*(ULONG)winpar.width)>>1; blocks=blsize/0x4000; rest=blsize%0x4000; cmd_read[7]=128; cmd_read[8]=0; for (i=0;i>7)&0xff; cmd_read[8]=(rest<<1)&0xff; DoScsi(&cmd_read,10,rdptr,rest<<1,DIR_READ); p64to16(rdptr,rest); rdptr+=rest; } while (glin); } DoScsi(&cmd_mdoff,6,NULL,0,0); } } static ULONG cmpline(UBYTE *zeile, UWORD len, UWORD pnum, FILE *qdatei) { ULONG count; UWORD plen,p; UBYTE m; WORD i,j; static UBYTE cplane[6000]; count=0; plen=len/pnum; for (p=0;p>1: ((ULONG)memwidth*(ULONG)memheight)>>3; memadd=(memgray)?((ULONG)memwidth*ADDLIN)>>1: ((ULONG)memwidth*ADDLIN)>>3; if ((memptr=(UBYTE*)malloc(memsize+memadd))==NULL) { MessReq((UBYTE*)"Out of Memmory!"); fclose(sdatei); } else { memneed=memsize; while (bflag) /* hier CMAP und Body suchen */ { fread(&chunk_hd[0],8,1,sdatei); if (chunk_hd[0]==BODY) bflag=0; else fseek(sdatei,chunk_hd[1],SEEK_CUR); } if (memgray) { loadptr=memptr; memset(&planes[0],0,4000); if (iffheader.cmp) for (i=0;i128) { fread(&cval,1,1,sdatei); for (i=0;i<(257-cnt);i++) planes[t++]=cval; } if (cnt<128) { fread(&planes[t],++cnt,1,sdatei); t+=cnt; } } fplanegen(loadptr,&planes[0],&planes[memwidth>>3], &planes[2*(memwidth>>3)],&planes[3*(memwidth>>3)],(memwidth>>3)); loadptr+=(memwidth>>1); } else for (i=0;i>3),1,sdatei); fplanegen(loadptr,&planes[0],&planes[memwidth>>3], &planes[2*(memwidth>>3)],&planes[3*(memwidth>>3)],(memwidth>>3)); loadptr+=(memwidth>>1); } } else { if (iffheader.cmp) { loadptr=memptr; while ((fread(&cnt,1,1,sdatei))) { if (cnt>128) { fread(&cval,1,1,sdatei); for (i=0;i<(257-cnt);i++) *(loadptr++)=cval; } if (cnt<128) { fread(loadptr,++cnt,1,sdatei); loadptr+=cnt; } } } else fread(memptr,(iffheader.w>>3)*iffheader.h,1,sdatei); } fclose(sdatei); } } } } void save(UWORD wx1,UWORD wy1,UWORD wx2,UWORD wy2,UBYTE cmp,UBYTE mf) { FILE *qdatei; ULONG totlen,bmlen; UWORD width,height,i,t; ULONG startofs,cmplen; UBYTE *saveptr; UBYTE planes[4000]; UBYTE sf; UBYTE dummy=0; if (filerequest("Save IFF File",str_filenam)) { sf=(memgray)?1:3; if (mf==2) { if (wx1>wx2) {t=wx2; wx2=wx1; wx1=t;} if (wy1>wy2) {t=wy2; wy2=wy1; wy1=t;} width=(wx2-wx1); height=(wy2-wy1); startofs=wy1*(memwidth>>sf)+(wx1>>sf); } else { width=memwidth; height=memheight; startofs=0; } width&=0xfff0; qdatei=fopen(str_filenam,"wb"); bmlen=(memgray)?((width>>1)*height):((width>>3)*height); totlen=bmlen+40+((memgray)?56:14); iff_head[1]=totlen; iff_head[5]=(width<<16)|height; iff_head[7]=((memgray)?0x04000000:0x01000000)|((cmp)?0x0100:0); iff_body[1]=bmlen; fwrite(&iff_head[0],sizeof(iff_head),1,qdatei); if (memgray) fwrite(iff_cmap_gray,sizeof(iff_cmap_gray),1,qdatei); else fwrite(iff_cmap_bw,sizeof(iff_cmap_bw),1,qdatei); fwrite(iff_body,sizeof(iff_body),1,qdatei); saveptr=memptr+startofs; cmplen=0; if (memgray) for (i=0;i>3],&planes[2*(width>>3)],&planes[3*(width>>3)],(width>>3)); if (cmp) cmplen+=cmpline(&planes[0],width>>1,4,qdatei); else fwrite(&planes[0],width>>1,1,qdatei); saveptr+=(ULONG)(memwidth>>1); } else for (i=0;i>3,1,qdatei); else fwrite(saveptr,width>>3,1,qdatei); saveptr+=(ULONG)(memwidth>>3); } if (cmp) { if (cmplen&1) fwrite(&dummy,1,1,qdatei); fseek(qdatei,sizeof(iff_head)+((memgray)?(sizeof(iff_cmap_gray)): (sizeof(iff_cmap_bw)))+4,SEEK_SET); fwrite(&cmplen,4,1,qdatei); if (cmplen&1) cmplen++; fseek(qdatei,4,SEEK_SET); cmplen+=((memgray)?96:54); fwrite(&cmplen,4,1,qdatei); } fclose(qdatei); } } void view(UWORD x, UWORD y, UBYTE zoom) { UBYTE *vptr; UBYTE *plptr[4]; ULONG vinc; ULONG vicr[13]; UWORD i,j,k,n1,n2,zeile; UBYTE linebuf[1000]; for (i=0;i<4;i++) plptr[i]=(UBYTE *)(rp->BitMap->Planes[i]+1680); vptr=(memgray)? (UBYTE*)(memptr+(((memwidth>>1)*y)+(x>>1))): (UBYTE*)(memptr+(((memwidth>>3)*y)+(x>>3))); vinc=(memgray)?(ULONG)(memwidth>>1):(ULONG)(memwidth>>3); if (zoom) { if ((memheight/4)>1);i+=4) { n1=n2=0; j=i; for (k=0;k<4;k++) { n1+=((*(vptr+j )>>4)+(*(vptr+j )&15)+(*(vptr+j+1)>>4)+(*(vptr+j+1)&15)); n2+=((*(vptr+j+2)>>4)+(*(vptr+j+2)&15)+(*(vptr+j+3)>>4)+(*(vptr+j+3)&15)); j+=vinc; } linebuf[i>>2]=(n1&0xf0)|(n2>>4); } vplanesep(&linebuf[0],plptr[0],plptr[1],plptr[2],plptr[3],memwidth>>5); plptr[0]+=80; plptr[1]+=80; plptr[2]+=80; plptr[3]+=80; vptr+=vicr[4]; } break; case 8: while(zeile>1);i+=8) { n1=n2=0; j=i; for (k=0;k<8;k++) { n1+=((*(vptr+j )>>4)+(*(vptr+j )&15)+(*(vptr+j+1)>>4)+(*(vptr+j+1)&15) +(*(vptr+j+2)>>4)+(*(vptr+j+2)&15)+(*(vptr+j+3)>>4)+(*(vptr+j+3)&15)); n2+=((*(vptr+j+4)>>4)+(*(vptr+j+4)&15)+(*(vptr+j+5)>>4)+(*(vptr+j+5)&15) +(*(vptr+j+6)>>4)+(*(vptr+j+6)&15)+(*(vptr+j+7)>>4)+(*(vptr+j+7)&15)); j+=vinc; } linebuf[i>>3]=((n1>>2)&0xf0)|((n2>>6)&0x0f); } vplanesep(&linebuf[0],plptr[0],plptr[1],plptr[2],plptr[3],memwidth>>6); plptr[0]+=80; plptr[1]+=80; plptr[2]+=80; plptr[3]+=80; vptr+=vicr[8]; } break; case 12:while(zeile>1);i+=12) { n1=n2=0; j=i; for (k=0;k<12;k++) { n1+=((*(vptr+j )>>4)+(*(vptr+j )&15)+(*(vptr+j+ 1)>>4)+(*(vptr+j+ 1)&15) +(*(vptr+j+ 2)>>4)+(*(vptr+j+ 2)&15)+(*(vptr+j+ 3)>>4)+(*(vptr+j+ 3)&15) +(*(vptr+j+ 4)>>4)+(*(vptr+j+ 4)&15)+(*(vptr+j+ 5)>>4)+(*(vptr+j+ 5)&15)); n2+=((*(vptr+j+ 6)>>4)+(*(vptr+j+ 6)&15)+(*(vptr+j+ 7)>>4)+(*(vptr+j+ 7)&15) +(*(vptr+j+ 8)>>4)+(*(vptr+j+ 8)&15)+(*(vptr+j+ 9)>>4)+(*(vptr+j+ 9)&15) +(*(vptr+j+10)>>4)+(*(vptr+j+10)&15)+(*(vptr+j+11)>>4)+(*(vptr+j+11)&15)); j+=vinc; } linebuf[i/12]=(((n1/144)<<4)&0xf0)|((n2/144)&0x0f); } vplanesep(&linebuf[0],plptr[0],plptr[1],plptr[2],plptr[3],memwidth/96); plptr[0]+=80; plptr[1]+=80; plptr[2]+=80; plptr[3]+=80; vptr+=vicr[12]; } break; } else switch (sk) { case 4: while(zeile>3);i++) { n1=numbits[(*(vptr+i ))>>4]+numbits[(*(vptr+i+vicr[1]))>>4] +numbits[(*(vptr+i+vicr[2]))>>4]+numbits[(*(vptr+i+vicr[3]))>>4]; if (n1==16) n1=15; n2=numbits[(*(vptr+i ))&15]+numbits[(*(vptr+i+vicr[1]))&15] +numbits[(*(vptr+i+vicr[2]))&15]+numbits[(*(vptr+i+vicr[3]))&15]; if (n2==16) n2=15; linebuf[i]=(~((n1<<4)|n2)); } vplanesep(&linebuf[0],plptr[0],plptr[1],plptr[2],plptr[3],memwidth>>5); plptr[0]+=80; plptr[1]+=80; plptr[2]+=80; plptr[3]+=80; vptr+=vicr[4]; } break; case 8: while(zeile>3);i+=2) { n1=(numbits[(*(vptr+i ))] +numbits[(*(vptr+i+vicr[1]))] +numbits[(*(vptr+i+vicr[2]))] +numbits[(*(vptr+i+vicr[3]))] +numbits[(*(vptr+i+vicr[4]))] +numbits[(*(vptr+i+vicr[5]))] +numbits[(*(vptr+i+vicr[6]))] +numbits[(*(vptr+i+vicr[7]))])>>2; if (n1==16) n1=15; n2=(numbits[(*(vptr+i+1 ))] +numbits[(*(vptr+i+1+vicr[1]))] +numbits[(*(vptr+i+1+vicr[2]))] +numbits[(*(vptr+i+1+vicr[3]))] +numbits[(*(vptr+i+1+vicr[4]))] +numbits[(*(vptr+i+1+vicr[5]))] +numbits[(*(vptr+i+1+vicr[6]))] +numbits[(*(vptr+i+1+vicr[7]))])>>2; if (n2==16) n2=15; linebuf[i>>1]=(~((n1<<4)|n2)); } vplanesep(&linebuf[0],plptr[0],plptr[1],plptr[2],plptr[3],memwidth>>6); plptr[0]+=80; plptr[1]+=80; plptr[2]+=80; plptr[3]+=80; vptr+=vicr[8]; } break; case 12:while(zeile>3);i+=3) { n1=(numbits[(*(vptr+i ))] +numbits[(*(vptr+i+ vicr[ 1]))] +numbits[(*(vptr+i+ vicr[ 2]))] +numbits[(*(vptr+i+ vicr[ 3]))] +numbits[(*(vptr+i+ vicr[ 4]))] +numbits[(*(vptr+i+ vicr[ 5]))] +numbits[(*(vptr+i+ vicr[ 6]))] +numbits[(*(vptr+i+ vicr[ 7]))] +numbits[(*(vptr+i+ vicr[ 8]))] +numbits[(*(vptr+i+ vicr[ 9]))] +numbits[(*(vptr+i+ vicr[10]))] +numbits[(*(vptr+i+ vicr[11]))] +numbits[(*(vptr+i+1 ))>>4] +numbits[(*(vptr+i+1+vicr[ 1]))>>4] +numbits[(*(vptr+i+1+vicr[ 2]))>>4] +numbits[(*(vptr+i+1+vicr[ 3]))>>4] +numbits[(*(vptr+i+1+vicr[ 4]))>>4] +numbits[(*(vptr+i+1+vicr[ 5]))>>4] +numbits[(*(vptr+i+1+vicr[ 6]))>>4] +numbits[(*(vptr+i+1+vicr[ 7]))>>4] +numbits[(*(vptr+i+1+vicr[ 8]))>>4] +numbits[(*(vptr+i+1+vicr[ 9]))>>4] +numbits[(*(vptr+i+1+vicr[10]))>>4] +numbits[(*(vptr+i+1+vicr[11]))>>4]); n2=(numbits[(*(vptr+i+2 ))] +numbits[(*(vptr+i+2+vicr[ 1]))] +numbits[(*(vptr+i+2+vicr[ 2]))] +numbits[(*(vptr+i+2+vicr[ 3]))] +numbits[(*(vptr+i+2+vicr[ 4]))] +numbits[(*(vptr+i+2+vicr[ 5]))] +numbits[(*(vptr+i+2+vicr[ 6]))] +numbits[(*(vptr+i+2+vicr[ 7]))] +numbits[(*(vptr+i+2+vicr[ 8]))] +numbits[(*(vptr+i+2+vicr[ 9]))] +numbits[(*(vptr+i+2+vicr[10]))] +numbits[(*(vptr+i+2+vicr[11]))] +numbits[(*(vptr+i+1 ))&15] +numbits[(*(vptr+i+1+vicr[ 1]))&15] +numbits[(*(vptr+i+1+vicr[ 2]))&15] +numbits[(*(vptr+i+1+vicr[ 3]))&15] +numbits[(*(vptr+i+1+vicr[ 4]))&15] +numbits[(*(vptr+i+1+vicr[ 5]))&15] +numbits[(*(vptr+i+1+vicr[ 6]))&15] +numbits[(*(vptr+i+1+vicr[ 7]))&15] +numbits[(*(vptr+i+1+vicr[ 8]))&15] +numbits[(*(vptr+i+1+vicr[ 9]))&15] +numbits[(*(vptr+i+1+vicr[10]))&15] +numbits[(*(vptr+i+1+vicr[11]))&15]); n1=n1/9; n2=n2/9; if (n1==16) n1=15; if (n2==16) n2=15; linebuf[i/3]=(~((n1<<4)|n2)); } vplanesep(&linebuf[0],plptr[0],plptr[1],plptr[2],plptr[3],memwidth/96); plptr[0]+=80; plptr[1]+=80; plptr[2]+=80; plptr[3]+=80; vptr+=vicr[12]; } break; } } else { vx=x&0xfff0; vy=y&0xfffe; sk=1; if (memgray) grayview(vptr,plptr[0],plptr[1],plptr[2],plptr[3],vinc); else bwview(vptr,plptr[0],plptr[1],plptr[2],plptr[3],vinc); } } UWORD s2px(UWORD x) { int t; t=x*sk+vx; if (t>=memwidth) t=memwidth-1; if (t<0) t=0; return((UWORD)t); } UWORD s2py(UWORD y) { int t; t=y*sk+vy; if (t>=memheight) t=memheight-1; if (t<0) t=0; return((UWORD)t); } UWORD p2sx(UWORD x) { int t; t=(x-vx)/sk; if (t>623) t=623; if (t<0) t=0; return((UWORD)t); } UWORD p2sy(UWORD y) { int t; t=(y-vy)/sk; if (t>(VIEWHEIGHT-1)) t=VIEWHEIGHT-1; if (t<0) t=0; return((UWORD)t); } void drawbox(UWORD wx1,UWORD wy1,UWORD wx2,UWORD wy2,struct RastPort *wrp) { UWORD sx1,sy1,sx2,sy2; sx1=p2sx(wx1); sy1=p2sy(wy1)+11; sx2=p2sx(wx2); sy2=p2sy(wy2)+11; SetWrMsk(wrp,8); SetAPen(wrp,8); SetDrMd(wrp,COMPLEMENT|JAM1); SetDrPt(wrp,0xcccc); Move(wrp,sx1,sy1); Draw(wrp,sx1,sy2); Draw(wrp,sx2,sy2); Draw(wrp,sx2,sy1); Draw(wrp,sx1,sy1); SetWrMsk(wrp,1); SetAPen(wrp,1); SetDrMd(wrp,COMPLEMENT|JAM1); SetDrPt(wrp,0x3333); Move(wrp,sx1,sy1); Draw(wrp,sx1,sy2); Draw(wrp,sx2,sy2); Draw(wrp,sx2,sy1); Draw(wrp,sx1,sy1); SetWrMsk(wrp,15); } void cut(UWORD wx1,UWORD wy1,UWORD wx2,UWORD wy2,UBYTE mf) { UWORD width,height,x,y,t; ULONG startofs; UBYTE *picptr,*cpyptr; UBYTE sf; sf=(memgray)?1:3; if ((memwidth<=640)||(memheight<=512)) MessReq("Area already has minimal size"); if (mf!=2) MessReq("No Area selected!"); else { if (wx1>wx2) {t=wx2; wx2=wx1; wx1=t;} if (wy1>wy2) {t=wy2; wy2=wy1; wy1=t;} width=(wx2-wx1); height=(wy2-wy1); if (height<512) { height=512; if ((wy1+height)>memheight) wy1=memheight-height; } if (width<640) { width=640; if ((wx1+width)>memwidth) wx1=memwidth-width; } startofs=wy1*(memwidth>>sf)+(wx1>>sf); picptr=memptr; for (y=0;y>sf);x++) *(picptr++)=*(cpyptr++); startofs+=(ULONG)(memwidth>>sf); } mf=0; memwidth=width; memheight=height; if (!(memptr=(UBYTE *)realloc(memptr,(memwidth*(memheight+ADDLIN))>>sf))) { memneed=0; MessReq((UBYTE *)"Out Of Memory!"); } } }