/* ST-400 Scanner Programm */
#include <exec/exec.h>
#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <graphics/rastport.h>
#include <libraries/reqbase.h>
#include <req_pragmas.h>
#include <stdio.h>
#include <string.h>
#include <functions.h>
#include "stscan.h"

#define PRG_VERSION (UBYTE *)"Version 2.00"
#define ST400ID 3
#define DEV_NAME (char*)"scsi.device" /* <- change for other SCSI controller */


char *_procname="StScan";
long _BackGroundIO=0;
long _stack=50000;
long _priority=0;
const short asmlines=VIEWHEIGHT-1;

struct Window *win;
struct IOStdReq *diskreq;
struct Viewport *vp;
struct RastPort *rp;
ULONG memneed;
UWORD memwidth, memheight;
UWORD membpl; /*für Verdünnung benötigt */
UBYTE memgray;
UBYTE *memptr;

static UBYTE mf,cmp;
static struct RastPort *wrp;
static struct MsgPort *HCPort;
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct DosBase *DosBase;
struct ReqBase *ReqBase;
static struct IntuiMessage *Message;
static struct Screen *scr;
static struct MsgPort *diskport;
static long openerror;
static UBYTE noscan;
static USHORT *imgptrf, *imgptrz;
static UWORD wx1,wy1,wx2,wy2;
static UBYTE numbits_16[]={0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};

UBYTE graystep[]={0,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1};
UBYTE bitval[]={128,64,32,16,8,4,2,1};
UBYTE invbitval[]={127,191,223,239,247,251,253,254};
UBYTE revbit[]={
   0, 128,  64, 192,  32, 160,  96, 224,  16, 144,  80, 208,  48, 176, 112, 240,
   8, 136,  72, 200,  40, 168, 104, 232,  24, 152,  88, 216,  56, 184, 120, 248,
   4, 132,  68, 196,  36, 164, 100, 228,  20, 148,  84, 212,  52, 180, 116, 244,
  12, 140,  76, 204,  44, 172, 108, 236,  28, 156,  92, 220,  60, 188, 124, 252,
   2, 130,  66, 194,  34, 162,  98, 226,  18, 146,  82, 210,  50, 178, 114, 242,
  10, 138,  74, 202,  42, 170, 106, 234,  26, 154,  90, 218,  58, 186, 122, 250,
   6, 134,  70, 198,  38, 166, 102, 230,  22, 150,  86, 214,  54, 182, 118, 246,
  14, 142,  78, 206,  46, 174, 110, 238,  30, 158,  94, 222,  62, 190, 126, 254,
   1, 129,  65, 193,  33, 161,  97, 225,  17, 145,  81, 209,  49, 177, 113, 241,
   9, 137,  73, 201,  41, 169, 105, 233,  25, 153,  89, 217,  57, 185, 121, 249,
   5, 133,  69, 197,  37, 165, 101, 229,  21, 149,  85, 213,  53, 181, 117, 245,
  13, 141,  77, 205,  45, 173, 109, 237,  29, 157,  93, 221,  61, 189, 125, 253,
   3, 131,  67, 195,  35, 163,  99, 227,  19, 147,  83, 211,  51, 179, 115, 243,
  11, 139,  75, 203,  43, 171, 107, 235,  27, 155,  91, 219,  59, 187, 123, 251,
   7, 135,  71, 199,  39, 167, 103, 231,  23, 151,  87, 215,  55, 183, 119, 247,
  15, 143,  79, 207,  47, 175, 111, 239,  31, 159,  95, 223,  63, 191, 127, 255
};

struct DefWindow winpar= /*default values */
{  0,0,32,	/*dummy1, dummy2, wpsize*/
   1,0,		/*winnr, dummy3*/
   200,200,	/*resx, resy*/
   0,0,0,0,	/*cornerx, cornery, width, height*/
   0,32,5,	/*dummy4, threshold, size*/
   0,1,		/*halftone, bitspixel*/
   0,0,0	/*dummy5,6,7*/
};

USHORT imagedataf[]=
{ 0xfff0,
  0xfff0,
  0xc030,
  0xdff0,
  0xdff0,
  0xc0f0,
  0xdff0,
  0xdff0,
  0xdff0,
  0xdff0,
  0xfff0,
  0xfff0,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000};
USHORT imagedataz[]=
{ 0xfff0,
  0xfff0,
  0xc030,
  0xff70,
  0xfef0,
  0xfdf0,
  0xfbf0,
  0xf7f0,
  0xeff0,
  0xc030,
  0xfff0,
  0xfff0,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000};

/* Struktures for Windows and Menus */

struct TextAttr textattr=
{ "topaz.FONT",
   8,
   FS_NORMAL,
   FPF_ROMFONT
};

/* Struktures for Gadgets */

USHORT zvect2[]={0,0, 0,12, 12,12, 12,0, 0,0,
                -1,-1, -1,11, 11,11, 11,-1, -1,-1};
USHORT zvect1[]={0,0, 0,10, 10,10, 10,0, 0,0};

struct Image fullimage=
{ 0,0,
  16,16,4,
  NULL,
  15,0,
  NULL
};

struct Image zoomimage=
{ 0,0,
  16,16,4,
  NULL,
  15,0,
  NULL
};

struct Border vborder;

struct Border hborder;


struct PropInfo hprop=
{ FREEHORIZ|AUTOKNOB,
  0,0,
  0xffff,0xffff,
  0,0,
  0,0,
  0,0
};

struct PropInfo vprop=
{ FREEVERT|AUTOKNOB,
  0,0,
  0xffff,0xffff,
  0,0,
  0,0,
  0,0
};

struct Gadget hgad=
{ NULL,
  0,VIEWHEIGHT+13,
  624,15,
  0,
  GADGIMMEDIATE|RELVERIFY,
  PROPGADGET,
  &hborder,
  NULL,
  NULL,
  0,
  &hprop,
  2,
  NULL
};

struct Gadget vgad=
{ &hgad,
  625,11,
  15,VIEWHEIGHT,
  0,
  GADGIMMEDIATE|RELVERIFY,
  PROPGADGET,
  &vborder,
  NULL,
  NULL,
  0,
  &vprop,
  1,
  NULL
};

struct Gadget zgad=
{ &vgad,
  627,VIEWHEIGHT+15,
  12,12,
  GADGHIMAGE|GADGIMAGE,
  TOGGLESELECT|GADGIMMEDIATE|RELVERIFY,
  BOOLGADGET,
  &fullimage,
  &zoomimage,
  NULL,
  0,
  NULL,
  0,
  NULL
};

/* Struktures for Window and Screen */

struct NewScreen ns=
{
  0,0,
  640,SCREENHEIGHT,
  4,
  8,1,
  HIRES|LACE,
  CUSTOMSCREEN,
  &textattr,
  (UBYTE *)"Siemens ST 400 Scanner Program © FChK 1991",
  NULL,
  NULL
};

struct NewWindow nw=
{ 0,10,
  640,SCREENHEIGHT-12,
  8,1,
  CLOSEWINDOW|MENUPICK|GADGETUP|GADGETDOWN|MOUSEBUTTONS,
  WINDOWCLOSE|BACKDROP|BORDERLESS|ACTIVATE|SMART_REFRESH,
  &zgad,
  NULL,
  (UBYTE *)"",
  NULL,
  NULL,
  0,0,
  0,0,
  CUSTOMSCREEN
};

/* AHA-Requester Strukturen */

struct IntuiText text_na=
{ 0,1,
  JAM2,
  4,7,
  &textattr,
  (UBYTE *)"",
  NULL
};

struct IntuiText text_aha=
{ 0,1,
  JAM2,
  7,4,
  &textattr,
  (UBYTE *)"OK!",
  NULL
};


/* Menüdaten und -strukturen */

struct IntuiText text131=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"   Compressed",
  NULL
};

struct IntuiText text130=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"   Raw Data",
  NULL
};


struct IntuiText text23f=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"   15",
  NULL
};

struct IntuiText text23e=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"   14",
  NULL
};

struct IntuiText text23d=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"   13",
  NULL
};

struct IntuiText text23c=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"   12",
  NULL
};

struct IntuiText text23b=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"   11",
  NULL
};

struct IntuiText text23a=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"   10",
  NULL
};

struct IntuiText text239=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"    9",
  NULL
};

struct IntuiText text238=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"    8",
  NULL
};

struct IntuiText text237=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"    7",
  NULL
};

struct IntuiText text236=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"    6",
  NULL
};

struct IntuiText text235=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"    5",
  NULL
};

struct IntuiText text234=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"    4",
  NULL
};

struct IntuiText text233=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"    3",
  NULL
};

struct IntuiText text232=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"    2",
  NULL
};

struct IntuiText text231=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"    1",
  NULL
};

struct IntuiText text230=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"    0",
  NULL
};

struct IntuiText text221=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"   16",
  NULL
};

struct IntuiText text220=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"    2",
  NULL
};

struct IntuiText text211=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"   DIN A4",
  NULL
};

struct IntuiText text210=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"   DIN A5",
  NULL
};

struct IntuiText text202=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"   400 DPI",
  NULL
};

struct IntuiText text201=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"   300 DPI",
  NULL
};

struct IntuiText text200=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"   200 DPI",
  NULL
};

struct IntuiText text53=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Cut",
  NULL
};

struct IntuiText text52=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Mirror V",
  NULL
};

struct IntuiText text51=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Mirror H",
  NULL
};

struct IntuiText text50=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Invert",
  NULL
};

struct IntuiText text43=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Set Accuracy",
  NULL
};

struct IntuiText text42=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Vectorize",
  NULL
};

struct IntuiText text41=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Thinning",
  NULL
};

struct IntuiText text40=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"To Gray",
  NULL
};

struct IntuiText text3b=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Median",
  NULL
};

struct IntuiText text3a=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Maximum",
  NULL
};

struct IntuiText text39=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Minimum",
  NULL
};

struct IntuiText text38=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Relief",
  NULL
};

struct IntuiText text37=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"VeryLow Pass",
  NULL
};

struct IntuiText text36=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"High Pass",
  NULL
};

struct IntuiText text35=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Low Pass",
  NULL
};

struct IntuiText text34=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Stretch Histo",
  NULL
};

struct IntuiText text33=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"View Histo",
  NULL
};

struct IntuiText text32=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Binarize",
  NULL
};

struct IntuiText text31=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Dither Ord",
  NULL
};

struct IntuiText text30=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Dither F-S",
  NULL
};

struct IntuiText text23=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Threshold",
  NULL
};

struct IntuiText text22=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Grayscale",
  NULL
};

struct IntuiText text21=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Size",
  NULL
};

struct IntuiText text20=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Resolution",
  NULL
};

struct IntuiText text15=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Exit Program",
  NULL
};

struct IntuiText text14=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Test Scanner",
  NULL
};

struct IntuiText text13=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Save Method...",
  NULL
};

struct IntuiText text12=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Save IFF",
  NULL
};

struct IntuiText text11=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Load IFF",
  NULL
};

struct IntuiText text10=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Read Scanner",
  NULL
};

struct IntuiText text03=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Not For Commercial Use",
  NULL
};

struct IntuiText text02=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  PRG_VERSION,
  NULL
};


struct IntuiText text01=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Frank-Christian Krügel",
  NULL
};

struct IntuiText text00=
{ 0,1,
  JAM2,
  1,1,
  &textattr,
  (UBYTE *)"Program written by",
  NULL
};


struct MenuItem item131=
{ NULL,
  112,10,
  112,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT,
  0xfffd,
  (APTR)&text131,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item130=
{ &item131,
  112,0,
  112,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT|CHECKED,
  0xfffe,
  (APTR)&text130,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item23f=
{ NULL,
  120,70,
  40,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT,
  0x7fff,
  (APTR)&text23f,
  NULL,
  0, 
  NULL,
  0
};

struct MenuItem item23e=
{ &item23f,
  120,60,
  40,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT,
  0xbfff,
  (APTR)&text23e,
  NULL,
  0, 
  NULL,
  0
};

struct MenuItem item23d=
{ &item23e,
  120,50,
  40,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT,
  0xdfff,
  (APTR)&text23d,
  NULL,
  0, 
  NULL,
  0
};

struct MenuItem item23c=
{ &item23d,
  120,40,
  40,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT,
  0xefff,
  (APTR)&text23c,
  NULL,
  0, 
  NULL,
  0
};

struct MenuItem item23b=
{ &item23c,
  120,30,
  40,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT,
  0xf7ff,
  (APTR)&text23b,
  NULL,
  0, 
  NULL,
  0
};

struct MenuItem item23a=
{ &item23b,
  120,20,
  40,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT,
  0xfbff,
  (APTR)&text23a,
  NULL,
  0, 
  NULL,
  0
};

struct MenuItem item239=
{ &item23a,
  120,10,
  40,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT,
  0xfdff,
  (APTR)&text239,
  NULL,
  0, 
  NULL,
  0
};

struct MenuItem item238=
{ &item239,
  120,0,
  40,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT|CHECKED,
  0xfeff,
  (APTR)&text238,
  NULL,
  0, 
  NULL,
  0
};

struct MenuItem item237=
{ &item238,
  80,70,
  40,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT,
  0xff7f,
  (APTR)&text237,
  NULL,
  0, 
  NULL,
  0
};

struct MenuItem item236=
{ &item237,
  80,60,
  40,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT,
  0xffbf,
  (APTR)&text236,
  NULL,
  0, 
  NULL,
  0
};

struct MenuItem item235=
{ &item236,
  80,50,
  40,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT,
  0xffdf,
  (APTR)&text235,
  NULL,
  0, 
  NULL,
  0
};

struct MenuItem item234=
{ &item235,
  80,40,
  40,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT,
  0xffef,
  (APTR)&text234,
  NULL,
  0, 
  NULL,
  0
};

struct MenuItem item233=
{ &item234,
  80,30,
  40,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT,
  0xfff7,
  (APTR)&text233,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item232=
{ &item233,
  80,20,
  40,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT,
  0xfffb,
  (APTR)&text232,
  NULL,
  0, 
  NULL,
  0
};

struct MenuItem item231=
{ &item232,
  80,10,
  40,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT,
  0xfffd,
  (APTR)&text231,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item230=
{ &item231,
  80,0,
  40,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT,
  0xfffe,
  (APTR)&text230,
  NULL,
  0, 
  NULL,
  0
};


struct MenuItem item221=
{ NULL,
  80,10,
  80,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT|COMMSEQ,
  0xfffd,
  (APTR)&text221,
  NULL,
  'g', 
  NULL,
  0
};

struct MenuItem item220=
{ &item221,
  80,0,
  80,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT|CHECKED|COMMSEQ,
  0xfffe,
  (APTR)&text220,
  NULL,
  'z', 
  NULL,
  0
};


struct MenuItem item211=
{ NULL,
  80,10,
  112,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT|COMMSEQ,
  0xfffd,
  (APTR)&text211,
  NULL,
  'b', 
  NULL,
  0
};

struct MenuItem item210=
{ &item211,
  80,0,
  112,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT|CHECKED|COMMSEQ,
  0xfffe,
  (APTR)&text210,
  NULL,
  'a',
  NULL,
  0
};


struct MenuItem item202=
{ NULL,
  80,20,
  120,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT|COMMSEQ,
  0xfffb,
  (APTR)&text202,
  NULL,
  '4', 
  NULL,
  0
};

struct MenuItem item201=
{ &item202,
  80,10,
  120,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT|COMMSEQ,
  0xfffd,
  (APTR)&text201,
  NULL,
  '3', 
  NULL,
  0
};


struct MenuItem item200=
{ &item201,
  80,0,
  120,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|CHECKIT|CHECKED|COMMSEQ,
  0xfffe,
  (APTR)&text200,
  NULL,
  '2', 
  NULL,
  0
};


struct MenuItem item53=
{ NULL,
  0,30,
  88,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text53,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item52=
{ &item53,
  0,20,
  88,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text52,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item51=
{ &item52,
  0,10,
  88,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text51,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item50=
{ &item51,
  0,0,
  88,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text50,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item43=
{ NULL,
  0,30,
  96,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text43,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item42=
{ &item43,
  0,20,
  96,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text42,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item41=
{ &item42,
  0,10,
  96,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text41,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item40=
{ &item41,
  0,0,
  96,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text40,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item3b=
{ NULL,
  0,110,
  112,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text3b,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item3a=
{ &item3b,
  0,100,
  112,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text3a,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item39=
{ &item3a,
  0,90,
  112,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text39,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item38=
{ &item39,
  0,80,
  112,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text38,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item37=
{ &item38,
  0,70,
  112,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text37,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item36=
{ &item37,
  0,60,
  112,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text36,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item35=
{ &item36,
  0,50,
  112,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text35,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item34=
{ &item35,
  0,40,
  112,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text34,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item33=
{ &item34,
  0,30,
  112,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text33,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item32=
{ &item33,
  0,20,
  112,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text32,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item31=
{ &item32,
  0,10,
  112,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text31,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item30=
{ &item31,
  0,0,
  112,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text30,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item23=
{ NULL,
  0,30,
  120,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text23,
  NULL,
  0,
  &item230,
  0
};

struct MenuItem item22=
{ &item23,
  0,20,
  120,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text22,
  NULL,
  0,
  &item220,
  0
};

struct MenuItem item21=
{ &item22,
  0,10,
  120,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text21,
  NULL,
  0,
  &item210,
  0
};

struct MenuItem item20=
{ &item21,
  0,0,
  120,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED,
  0,
  (APTR)&text20,
  NULL,
  0,
  &item200,
  0
};

struct MenuItem item15=
{ NULL,
  0,50,
  176,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|COMMSEQ,
  0,
  (APTR)&text15,
  NULL,
  'x',
  NULL,
  0
};

struct MenuItem item14=
{ &item15,
  0,40,
  176,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|COMMSEQ,
  0,
  (APTR)&text14,
  NULL,
  't',
  NULL,
  0
};

struct MenuItem item13=
{ &item14,
  0,30,
  176,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|COMMSEQ,
  0,
  (APTR)&text13,
  NULL,
  'c',
  &item130,
  0
};

struct MenuItem item12=
{ &item13,
  0,20,
  176,10,
  ITEMTEXT|HIGHCOMP|COMMSEQ,
  0,
  (APTR)&text12,
  NULL,
  's',
  NULL,
  0
};
	
struct MenuItem item11=
{ &item12,
  0,10,
  176,10,
  ITEMTEXT|HIGHCOMP|COMMSEQ|ITEMENABLED,
  0,
  (APTR)&text11,
  NULL,
  'l',
  NULL,
  0
};
	
struct MenuItem item10=
{ &item11,
  0,0,
  176,10,
  ITEMTEXT|HIGHCOMP|ITEMENABLED|COMMSEQ,
  0,
  (APTR)&text10,
  NULL,
  'r',
  NULL,
  0
};

struct MenuItem item03=
{ NULL,
  0,30,
  160,10,
  ITEMTEXT|HIGHNONE|ITEMENABLED,
  0,
  (APTR)&text03,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item02=
{ &item03,
  0,20,
  160,10,
  ITEMTEXT|HIGHNONE|ITEMENABLED,
  0,
  (APTR)&text02,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item01=
{ &item02,
  0,10,
  160,10,
  ITEMTEXT|HIGHNONE|ITEMENABLED,
  0,
  (APTR)&text01,
  NULL,
  0,
  NULL,
  0
};

struct MenuItem item00=
{ &item01,
  0,0,
  160,10,
  ITEMTEXT|HIGHNONE|ITEMENABLED,
  0,
  (APTR)&text00,
  NULL,
  0,
  NULL,
  0
};

struct Menu menu5=
{ NULL,
  460,0,
  80,8,
  NULL,
  "Transform",
  &item50
};

struct Menu menu4=
{ &menu5,
  360,0,
  88,8,
  NULL,
  "BW Process",
  &item40
};

struct Menu menu3=
{ &menu4,
  250,0,
  104,8,
  NULL,
  "Gray Process",
  &item30
};

struct Menu menu2=
{ &menu3,
  160,0,
  72,8,
  MENUENABLED,
  "Settings",
  &item20
};

struct Menu menu1=
{ &menu2,
  64,0,
  64,8,
  MENUENABLED,
  "Program",
  &item10
};

struct Menu menu0=
{ &menu1,
  0,0,
  40,8,
  MENUENABLED,
  "Info",
  &item00
};

void ende()
{ if (memptr) free(memptr);
  if (!(noscan))
  { if(openerror==0)
    { CloseDevice(diskreq);
    }
    if(diskport)DeletePort(diskport);
    if(diskreq)DeleteStdIO(diskreq);
  }
  if (win) { ClearMenuStrip(win); CloseWindow(win); }
  if (scr) CloseScreen(scr); 
  if (imgptrf) FreeMem(imgptrf,sizeof(imagedataf));
  if (imgptrz) FreeMem(imgptrz,sizeof(imagedataz));
  if (ReqBase) CloseLibrary(ReqBase);
  if (DosBase) CloseLibrary(DosBase);
  if (GfxBase) CloseLibrary(GfxBase);
  if (IntuitionBase) CloseLibrary(IntuitionBase);
}

void menu(USHORT Code)
{
  USHORT num,item,subitem;
  num=MENUNUM(Code);
  item=ITEMNUM(Code);
  subitem=SUBNUM(Code);
  switch(num)
  {  case 0: break;                    /* Info */
     case 1: switch(item)              /* Programm */
             { case 0: scan();         /* Einlesen */
                       vprop.VertBody=(zgad.Flags&SELECTED)?0xffff:VIEWHEIGHT*65536/memheight;
                       hprop.HorizBody=(zgad.Flags&SELECTED)?0xffff:624*65536/memwidth;
                       vprop.VertPot=0;
                       hprop.HorizPot=0;
                       RefreshGadgets(&zgad,win,NULL);
                       if (memneed)
                       { view(0,0,(zgad.Flags&SELECTED));
                         mf=0;
                       }
                       break;
               case 1: load();
                       vprop.VertBody=(!(memheight))||(zgad.Flags&SELECTED)?0xffff:VIEWHEIGHT*65536/memheight;
                       hprop.HorizBody=(!(memwidth))||(zgad.Flags&SELECTED)?0xffff:624*65536/memwidth;
                       vprop.VertPot=0;
                       hprop.HorizPot=0;
                       RefreshGadgets(&zgad,win,NULL);
                       if (memneed)
                       { view(0,0,(zgad.Flags&SELECTED));
                         mf=0;
                       }
                       break;
               case 2: save(wx1,wy1,wx2,wy2,cmp,mf); /* Speichern */
                       break;
               case 3: cmp=subitem;
                       break;
               case 4: inquiry();
                       break;
               case 5: ende();         /* Ende */
                       exit(0L);
                       break;
             }
             break;
     case 2: switch(item)
             { case 0: winpar.resx=100*(subitem+2);
                       winpar.resy=winpar.resx;
                       break;
               case 1: winpar.size=5-subitem;
                       break;
               case 2: winpar.halftone=subitem<<1;
                       winpar.bitspixel=subitem ? 8 : 1;
                       break;
               case 3: winpar.threshold=subitem<<2;
                       break;
             }
             break;
     case 3: switch(item)
             { case 0: if ((memgray)&&(memneed))
                       { floyd();
                         if (memneed) view(hprop.HorizPot*(memwidth-624)/65536,
                                           vprop.VertPot*(memheight-VIEWHEIGHT)/65536,
                                           (zgad.Flags&SELECTED));
                         if (mf==2) drawbox(wx1,wy1,wx2,wy2,wrp);
                       }
                       break;
               case 1: if ((memgray)&&(memneed))
                       { ordered();
                         if (memneed) view(hprop.HorizPot*(memwidth-624)/65536,
                                           vprop.VertPot*(memheight-VIEWHEIGHT)/65536,
                                           (zgad.Flags&SELECTED));
                         if (mf==2) drawbox(wx1,wy1,wx2,wy2,wrp);
                       }
                       break;
               case 2: if ((memgray)&&(memneed))
                       { thresh(); 
                         if (memneed) view(hprop.HorizPot*(memwidth-624)/65536,
                                           vprop.VertPot*(memheight-VIEWHEIGHT)/65536,
                                           (zgad.Flags&SELECTED));
                         if (mf==2) drawbox(wx1,wy1,wx2,wy2,wrp);
                       }
                       break;
               case 3: if ((memgray)&&(memneed)) viewhisto(wrp);
                       break;
               case 4: if ((memgray)&&(memneed))
                       { stretchhisto(); 
                         if (memneed) view(hprop.HorizPot*(memwidth-624)/65536,
                                           vprop.VertPot*(memheight-VIEWHEIGHT)/65536,
                                           (zgad.Flags&SELECTED));
                         if (mf==2) drawbox(wx1,wy1,wx2,wy2,wrp);
                       }
                       break;
               case 5: if ((memgray)&&(memneed))
                       { lowpass(); 
                         if (memneed) view(hprop.HorizPot*(memwidth-624)/65536,
                                           vprop.VertPot*(memheight-VIEWHEIGHT)/65536,
                                           (zgad.Flags&SELECTED));
                         if (mf==2) drawbox(wx1,wy1,wx2,wy2,wrp);
                       }
                       break;
               case 6: if ((memgray)&&(memneed))
                       { highpass(); 
                         if (memneed) view(hprop.HorizPot*(memwidth-624)/65536,
                                           vprop.VertPot*(memheight-VIEWHEIGHT)/65536,
                                           (zgad.Flags&SELECTED));
                         if (mf==2) drawbox(wx1,wy1,wx2,wy2,wrp);
                       }
                       break;
               case 7: if ((memgray)&&(memneed))
                       { blowpass(); 
                         if (memneed) view(hprop.HorizPot*(memwidth-624)/65536,
                                           vprop.VertPot*(memheight-VIEWHEIGHT)/65536,
                                           (zgad.Flags&SELECTED));
                         if (mf==2) drawbox(wx1,wy1,wx2,wy2,wrp);
                       }
                       break;
               case 8: if ((memgray)&&(memneed))
                       { relief(); 
                         if (memneed) view(hprop.HorizPot*(memwidth-624)/65536,
                                           vprop.VertPot*(memheight-VIEWHEIGHT)/65536,
                                           (zgad.Flags&SELECTED));
                         if (mf==2) drawbox(wx1,wy1,wx2,wy2,wrp);
                       }
                       break;
               case 9: if ((memgray)&&(memneed))
                       { minop(); 
                         if (memneed) view(hprop.HorizPot*(memwidth-624)/65536,
                                           vprop.VertPot*(memheight-VIEWHEIGHT)/65536,
                                           (zgad.Flags&SELECTED));
                         if (mf==2) drawbox(wx1,wy1,wx2,wy2,wrp);
                       }
                       break;
               case 10:if ((memgray)&&(memneed))
                       { maxop(); 
                         if (memneed) view(hprop.HorizPot*(memwidth-624)/65536,
                                           vprop.VertPot*(memheight-VIEWHEIGHT)/65536,
                                           (zgad.Flags&SELECTED));
                         if (mf==2) drawbox(wx1,wy1,wx2,wy2,wrp);
                       }
                       break;
               case 11:if ((memgray)&&(memneed))
                       { median(); 
                         if (memneed) view(hprop.HorizPot*(memwidth-624)/65536,
                                           vprop.VertPot*(memheight-VIEWHEIGHT)/65536,
                                           (zgad.Flags&SELECTED));
                         if (mf==2) drawbox(wx1,wy1,wx2,wy2,wrp);
                       }
                       break;
             }
             break;
     case 4: switch(item)
             { case 0: if ((!(memgray))&&(memneed))
                       { togray();
                         if (memneed) view(hprop.HorizPot*(memwidth-624)/65536,
                                           vprop.VertPot*(memheight-VIEWHEIGHT)/65536,
                                           (zgad.Flags&SELECTED));
                         if (mf==2) drawbox(wx1,wy1,wx2,wy2,wrp);
                       }
                       break;
               case 1: if ((!(memgray))&&(memneed))
                       { thin();
                         if (memneed) view(hprop.HorizPot*(memwidth-624)/65536,
                                           vprop.VertPot*(memheight-VIEWHEIGHT)/65536,
                                           (zgad.Flags&SELECTED));
                         if (mf==2) drawbox(wx1,wy1,wx2,wy2,wrp);
                       }
                       break;
               case 2: if ((!(memgray))&&(memneed))
                       { vectorize();
                         if (memneed) view(hprop.HorizPot*(memwidth-624)/65536,
                                           vprop.VertPot*(memheight-VIEWHEIGHT)/65536,
                                           (zgad.Flags&SELECTED));
                         if (mf==2) drawbox(wx1,wy1,wx2,wy2,wrp);
                       }
                       break;
               case 3: chngmaxdiff();
                       break;
             }
             break;
     case 5: switch(item)
             { case 0: if (memneed)
                       { invert();
                         if (memneed) view(hprop.HorizPot*(memwidth-624)/65536,
                                           vprop.VertPot*(memheight-VIEWHEIGHT)/65536,
                                           (zgad.Flags&SELECTED));
                         if (mf==2) drawbox(wx1,wy1,wx2,wy2,wrp);
                       }
                       break;
               case 1: if (memneed)
                       { mirrorh();
                         if (memneed) view(hprop.HorizPot*(memwidth-624)/65536,
                                           vprop.VertPot*(memheight-VIEWHEIGHT)/65536,
                                           (zgad.Flags&SELECTED));
                         if (mf==2) drawbox(wx1,wy1,wx2,wy2,wrp);
                       }
                       break;
               case 2: if (memneed)
                       { mirrorv();
                         if (memneed) view(hprop.HorizPot*(memwidth-624)/65536,
                                           vprop.VertPot*(memheight-VIEWHEIGHT)/65536,
                                           (zgad.Flags&SELECTED));
                         if (mf==2) drawbox(wx1,wy1,wx2,wy2,wrp);
                       }
                       break;
               case 3: if (memneed)
                       { cut(wx1,wy1,wx2,wy2,mf);
                         if (memneed) view(hprop.HorizPot*(memwidth-624)/65536,
                                           vprop.VertPot*(memheight-VIEWHEIGHT)/65536,
                                           (zgad.Flags&SELECTED));
                         mf=0;
                       }
                       break;
             }
             break;
  }
}

void main()
{ static ULONG MessageClass;
  static USHORT Code;
  USHORT i;
  USHORT nr;
  UWORD mx,my;

  if ((IntuitionBase = (struct IntuitionBase *)
       OpenLibrary("intuition.library",0L)) == 0L)
  {    ende();
       exit(100L);
  }
  if ((GfxBase = (struct GfxBase *)
       OpenLibrary("graphics.library",0L))==0L)
  {    ende();
       exit(100L);
  }
  if ((DosBase = (struct DosBase *)
       OpenLibrary("dos.library",0L))==0L)
  {    ende();
       exit(100L);
  } 
  if ((ReqBase = (struct ReqBase *)
       OpenLibrary("req.library",0L))==0L)
  {    ende();
       exit(100L);
  } 
  if (!(imgptrf=AllocMem(sizeof(imagedataf),MEMF_CHIP)))
  {    ende();
       exit(85L);
  }
  if (!(imgptrz=AllocMem(sizeof(imagedataz),MEMF_CHIP)))
  {    ende();
       exit(85L);
  }
  memneed=0;
  noscan=0;
  memcpy(imgptrf,&imagedataf,sizeof(imagedataf));
  memcpy(imgptrz,&imagedataz,sizeof(imagedataz));
  fullimage.ImageData=(USHORT *)imgptrf;
  zoomimage.ImageData=(USHORT *)imgptrz;
  if (!(scr=(struct Screen*)OpenScreen(&ns)))
  {    ende();
       exit(90L);
  }
  vp=&scr->ViewPort;
  rp=&scr->RastPort;
  for (i=0;i<16;i++)
  { SetRGB4(vp,i,graystep[i],graystep[i],graystep[i]); }
  nw.Screen=scr;
  if (!(win=(struct Window *)OpenWindow(&nw)))
  {    ende();
       exit(90L);
  }
  wrp=win->RPort;
  if(!(diskport=CreatePort(0L,0L)))
  {    noscan=1;
  }
  if(!(diskreq=(struct IOStdReq *)CreateStdIO(diskport)))
  {    noscan=1;
       if(diskport)DeletePort(diskport);
  }
  if(openerror=OpenDevice(DEV_NAME,ST400ID,diskreq,0L))
  {    noscan=1;
       if(diskport)DeletePort(diskport);
       if(diskreq)DeleteStdIO(diskreq);
  }
  if (noscan)
  { item10.Flags&=(~ITEMENABLED);
    item14.Flags&=(~ITEMENABLED);
  }
  memptr=NULL; 
  cmp=mf=0;
  SetMenuStrip(win,&menu0);
  for (i=0;i<256;i++) numbits[i]=numbits_16[i/16]+numbits_16[i&15];
  SetWindowTitles(win,"No area selected                          ",(UBYTE *)-1);
  for(;;)
  { Wait((long)(1L<<win->UserPort->mp_SigBit));
    while (Message=(struct IntuiMessage *)GetMsg(win->UserPort))
    {
      MessageClass=Message->Class;
      Code=Message->Code;
      ReplyMsg(Message);
      if (MessageClass==MENUPICK) menu(Code);
      if (((MessageClass==GADGETUP))&&(memneed))
      { if (!(Message->IAddress->GadgetID))
        { vprop.VertBody=(zgad.Flags&SELECTED)?0xffff:VIEWHEIGHT*65536/memheight;
          hprop.HorizBody=(zgad.Flags&SELECTED)?0xffff:624*65536/memwidth;
          vprop.VertPot=0;
          hprop.HorizPot=0;
        }
        view(hprop.HorizPot*(memwidth-624)/65536,vprop.VertPot*(memheight-VIEWHEIGHT)/65536,(zgad.Flags&SELECTED));
        if (mf==2) drawbox(wx1,wy1,wx2,wy2,wrp);
        RefreshGadgets(&vgad,win,NULL);
      }
      if ((MessageClass==MOUSEBUTTONS)&&(Code&128)&&(memneed))
      { mx=win->MouseX; my=win->MouseY;
        if ((mx<624)&&(my>=10)&&(my<VIEWHEIGHT))
        switch(mf)
        { case 0: wx1=s2px(mx)&0xfff8; wy1=s2py(my-11); mf=1; break;
          case 1: wx2=s2px(mx)&0xfff8; wy2=s2py(my-11); mf=2; 
                  drawbox(wx1,wy1,wx2,wy2,wrp); break;
          case 2: mf=0; drawbox(wx1,wy1,wx2,wy2,wrp); break;
        }
      }
      if (MessageClass==CLOSEWINDOW)
      { ende();
        exit(0L);
      } /* if */
      if ((!(memgray))&&(memneed)) menu4.Flags|=MENUENABLED;
      else menu4.Flags&=(~MENUENABLED);
      if ((memgray)&&(memneed)) menu3.Flags|=MENUENABLED;
      else menu3.Flags&=(~MENUENABLED);
      if (memneed)
      { item12.Flags|=ITEMENABLED;
        menu5.Flags|=MENUENABLED;
      }
      else
      { item12.Flags&=(~ITEMENABLED);
        menu5.Flags&=(~MENUENABLED);
      }
      switch(mf)
      { case 0: SetWindowTitles(win,"No area selected                          ",(UBYTE *)-1);
                item53.Flags&=(~ITEMENABLED);
                break; 
        case 1: SetWindowTitles(win,"Select next point                         ",(UBYTE *)-1);
                item53.Flags&=(~ITEMENABLED);
                break; 
        case 2: SetWindowTitles(win,"Area selected                             ",(UBYTE *)-1);
                item53.Flags|=ITEMENABLED;
                break; 
      }
    } /* while */
  } /* for */
} /* main */

