home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / image144.sit / File1.p < prev    next >
Encoding:
Text File  |  1992-03-30  |  80.0 KB  |  2,951 lines

  1. unit File1;
  2.  
  3. {Routines used by Image for implementing File Menu commands.}
  4.  
  5. interface
  6.  
  7.  
  8.     uses
  9.         QuickDraw, Palettes, PrintTraps, globals, Utilities, Graphics, file2, sound, Lut;
  10.  
  11.  
  12.     function CloseAWindow (WhichWindow: WindowPtr): integer;
  13.     procedure DoClose;
  14.     function OpenFile (fname: str255; vnum: integer): boolean;
  15.     function OpenPict (fname: str255; vnum: integer; Reverting: boolean): boolean;
  16.     procedure SaveFile;
  17.     function DoOpen (FileName: str255; RefNum: integer): boolean;
  18.     function ImportFile (FileName: str255; RefNum: integer): boolean;
  19.     procedure RevertToSaved;
  20.     procedure SaveAs (name: str255; RefNum: integer);
  21.     procedure Export (name: str255; RefNum: integer);
  22.     procedure FindWhatToPrint;
  23.     procedure UpdateFileMenu;
  24.     procedure SaveAsText (fname: str255; RefNum: integer);
  25.     procedure SaveAll;
  26.     procedure UpdateWindowsMenuItem (PicSize: LongInt; title: str255; PicNum: integer);
  27.     procedure SaveScreen;
  28.     function OpenPICS (name: str255; fRefNum: integer): boolean;
  29.  
  30.  
  31. implementation
  32.  
  33.     var
  34.         OpenAllFiles, UseExistingLUT, PICTReadErr, UpdateIcons: boolean;
  35.         SaveRefNum: integer;
  36.         TempStackInfo: StackInfoRec;
  37.  
  38. {$PUSH}
  39. {$D-}
  40.  
  41.     function IOCheck (err: OSerr): integer;
  42.         var
  43.             ErrStr, Message: str255;
  44.             ignore: integer;
  45.     begin
  46.         if err <> 0 then begin
  47.                 Message := '';
  48.                 case err of
  49.                     -34: 
  50.                         Message := 'Disk Full';
  51.                     -36: 
  52.                         Message := 'I/O Error';
  53.                     -49: 
  54.                         Message := 'File in Use';
  55.                 end;
  56.                 NumToString(err, ErrStr);
  57.                 ParamText(Message, ErrStr, '', '');
  58.                 InitCursor;
  59.                 ignore := alert(IOErrorID, nil);
  60.                 macro := false; {If macro, abort it}
  61.             end;
  62.         IOCheck := err;
  63.     end;
  64.  
  65.     procedure LookForCluts (fname: str255; vnum: integer);
  66.         var
  67.             RefNum: integer;
  68.             err: OSErr;
  69.             ok1, ok2: boolean;
  70.     begin
  71.         if not UseExistingLUT then begin
  72.                 err := SetVol(nil, vnum);
  73.                 refNum := OpenResFile(fname);
  74.                 if RefNum <> -1 then begin
  75.                         ok1 := LoadCLUTResource(KlutzID);
  76.                         if not ok1 then
  77.                             ok2 := LoadCLUTResource(PixelPaintID);
  78.                         CloseResFile(refNum);
  79.                     end;
  80.             end;
  81.     end;
  82.  
  83.  
  84.     function OpenImageHeader (f: integer; fname: str255; vnum: integer): boolean;
  85.         var
  86.             ByteCount: LongInt;
  87.             err: OSErr;
  88.             TempHdr: PicHeader;
  89.             i, OldNExtra, p1x, p2x: integer;
  90.             ok: boolean;
  91.     begin
  92.         ByteCount := HeaderSize;
  93.         err := SetFPos(f, fsFromStart, info^.HeaderOffset);
  94.         err := fsread(f, ByteCount, @TempHdr);
  95.         if IOCheck(err) <> NoErr then begin
  96.                 OpenImageHeader := false;
  97.                 exit(OpenImageHeader);
  98.             end;
  99.         with info^, TempHdr do begin
  100.                 if PictureType <> TiffFile then begin
  101.                         nlines := hnlines;
  102.                         PixelsPerLine := hPixelsPerLine;
  103.                     end;
  104.                 if (hversion > 54) and not UseExistingLUT then begin
  105.                         OldNExtra := nExtraColors;
  106.                         nExtraColors := hnExtraColors;
  107.                         ExtraColors := hExtraColors;
  108.                         if (nExtraColors > 0) or (OldNExtra <> nExtraColors) then
  109.                             RedrawLUTWindow;
  110.                     end;
  111.                 if (hversion >= 42) and not UseExistingLUT then begin
  112.                         if hversion < 142 then begin
  113.                                 LUTMode := hOldLUTMode;
  114.                                 if (LutMode = OldAppleDefault) or (LutMode = OldSpectrum) then
  115.                                     LutMode := ColorLut;
  116.                             end
  117.                         else begin
  118.                                 LUTMode := hLUTMode;
  119.                                 if LutMode = Pseudocolor then begin
  120.                                         if ((hnColors > 32) and (hTable = CustomTable)) or (hTable > spectrum) then
  121.                                             LutMode := ColorLut;
  122.                                     end;
  123.                             end;
  124.                         case LUTMode of
  125.                             PseudoColor: 
  126.                                 if hversion < 142 then begin
  127.                                         nColors := hOldnColors;
  128.                                         for i := 0 to ncolors - 1 do begin
  129.                                                 RedLUT[i] := hr[i];
  130.                                                 GreenLUT[i] := hg[i];
  131.                                                 BlueLUT[i] := hb[i];
  132.                                             end;
  133.                                         ColorEnd := 255 - hOldColorStart;
  134.                                         ColorStart := ColorEnd - nColors * hColorWidth + 1;
  135.                                         if ColorStart < 0 then
  136.                                             ColorStart := 0;
  137.                                         InvertPalette;
  138.                                         FillColor1 := BlackRGB;
  139.                                         FillColor2 := BlackRGB;
  140.                                         ColorTable := CustomTable;
  141.                                         UpdateLUT;
  142.                                     end
  143.                                 else begin {V1.42 or later}
  144.                                         if (hTable <> CustomTable) and (hTable <= spectrum) then begin
  145.                                                 SwitchColorTables(GetColorTableItem(hTable), false);
  146.                                                 if hInvertedTable then
  147.                                                     InvertPalette;
  148.                                             end
  149.                                         else begin
  150.                                                 nColors := hnColors;
  151.                                                 ColorTable := CustomTable;
  152.                                                 if nColors <= 32 then
  153.                                                     for i := 0 to ncolors - 1 do begin
  154.                                                             RedLUT[i] := hr[i];
  155.                                                             GreenLUT[i] := hg[i];
  156.                                                             BlueLUT[i] := hb[i];
  157.                                                         end;
  158.                                             end;
  159.                                         ColorStart := hColorStart;
  160.                                         ColorEnd := hColorEnd;
  161.                                         FillColor1 := hFill1;
  162.                                         FillColor2 := hFill2;
  163.                                         UpdateLUT;
  164.                                         UpdateMap;
  165.                                     end; {v1.42 or later}
  166.                             GrayScale: 
  167.                                 ResetGrayMap;
  168.                             ColorLut, CustomGrayscale: 
  169.                                 if PictureType <> PictFile then begin
  170.                                         if ColorMapOffset > 0 then
  171.                                             GetTiffColorMap(f)
  172.                                         else
  173.                                             LookForCluts(fname, vnum);
  174.                                     end;
  175.                             otherwise
  176.                         end; {case}
  177.                         if hLutMode = CustomGrayscale then
  178.                             LutMode := CustomGrayscale;
  179.                     end;{if}
  180.                 if (hversion >= 65) and ((ForegroundIndex <> hForegroundIndex) or (BackgroundIndex <> hBackgroundIndex)) then begin
  181.                         SetForegroundColor(hForegroundIndex);
  182.                         SetBackgroundColor(hBackgroundIndex);
  183.                     end;
  184.                 if (hversion > 88) and (LUTMode = GrayScale) and not UseExistingLUT then begin
  185.                         if hversion < 138 then begin
  186.                                 p1x := 255 - hp2x;
  187.                                 p2x := 255 - hp1x;
  188.                             end
  189.                         else begin
  190.                                 p1x := hp1x;
  191.                                 p2x := hp2x
  192.                             end;
  193.                         nColors := 256;
  194.                         ColorStart := p1x;
  195.                         ColorEnd := p2x;
  196.                         UpdateLUT;
  197.                     end;
  198.                 if hversion > 106 then begin
  199.                         RawSpatialScale := hRawSpatialScale;
  200.                         if hversion > 124 then begin
  201.                                 ScaleMagnification := hScaleMagnification;
  202.                                 xSpatialScale := hRawSpatialScale * ScaleMagnification;
  203.                             end
  204.                         else begin
  205.                                 ScaleMagnification := 1.0;
  206.                                 xSpatialScale := hRawSpatialScale;
  207.                             end;
  208.                         ySpatialScale := xSpatialScale;
  209.                         PixelAspectRatio := 1.0;
  210.                         SpatiallyCalibrated := xSpatialScale <> 0.0;
  211.                     end;
  212.                 if hversion > 140 then begin
  213.                         PixelAspectRatio := hPixelAspectRatio;
  214.                         ySpatialScale := xSpatialScale / PixelAspectRatio;
  215.                     end;
  216.                 GetUnits(hUnitsID);
  217.                 if ((hnCoefficients > 0) and (hfit < UncalibratedOD)) or (hfit = UncalibratedOD) then begin
  218.                         if (hfit = SpareFit1) or (hfit = SpareFit2) then begin
  219.                                 DensityCalibrated := false;
  220.                                 DrawLabels('', '', '');
  221.                             end
  222.                         else begin
  223.                                 fit := hfit;
  224.                                 if hfit <> UncalibratedOD then begin
  225.                                         nCoefficients := hnCoefficients;
  226.                                         Coefficient := hCoeff;
  227.                                     end;
  228.                                 UnitOfMeasure := hUM;
  229.                                 DensityCalibrated := true;
  230.                                 if hversion >= 144 then
  231.                                     ZeroClip := hZeroClip
  232.                                 else
  233.                                     ZeroClip := false;
  234.                                 GenerateValues;
  235.                             end;
  236.                     end
  237.                 else begin
  238.                         DensityCalibrated := false;
  239.                         DrawLabels('', '', '');
  240.                     end;
  241.                 BinaryPic := hBinaryPic;
  242.                 if hSliceEnd > 1 then begin
  243.                         SliceStart := hSliceStart;
  244.                         SliceEnd := hSliceEnd;
  245.                         if SliceEnd > 254 then
  246.                             SliceEnd := 254;
  247.                     end;
  248.                 if hNSlices > 1 then begin
  249.                         with TempStackInfo do begin
  250.                                 nSlices := hNSlices;
  251.                                 if nSlices > MaxSlices then
  252.                                     nSlices := MaxSlices;
  253.                                 CurrentSlice := hCurrentSlice;
  254.                                 if (hCurrentSlice < 1) or (hCurrentSlice > nSlices) then
  255.                                     CurrentSlice := 1;
  256.                                 SliceSpacing := hSliceSpacing;
  257.                                 LoopTime := hLoopTime;
  258.                             end;
  259.                     end;
  260.                 OpenImageHeader := true
  261.             end;
  262.     end;
  263.  
  264.  
  265.     function OpenHeader (f: integer; fname: str255; vnum: integer; var NextTiffIFD: LongInt): boolean;
  266.         var
  267.             ByteCount, FileSize, DirOffset: LongInt;
  268.             hdr: packed array[1..512] of byte;
  269.             err: OSErr;
  270.             TempHdr: PicHeader;
  271.             TiffInfo: TiffInfoRec;
  272.     begin
  273.         with info^ do begin
  274.                 if (WhatToOpen = OpenUnknown) or (WhatToOpen = OpenImported) then begin
  275.                         err := SetFPos(f, fsFromStart, 0);
  276.                         ByteCount := 8;
  277.                         err := fsread(f, ByteCount, @hdr);
  278.                         if ((hdr[1] = 73) and (hdr[2] = 73)) or ((hdr[1] = 77) and (hdr[2] = 77)) then
  279.                             WhatToOpen := OpenTIFF
  280.                         else if WhatToOpen = OpenUnknown then
  281.                             WhatToOpen := OpenImage
  282.                         else
  283.                             WhatToOpen := OpenMCID;
  284.                     end;
  285.                 StackInfo := nil;
  286.                 with TempStackInfo do begin
  287.                         TempStackInfo.nSlices := 0;
  288.                         CurrentSlice := 1;
  289.                         SliceSpacing := 0.0;
  290.                         LoopTime := 0.0;
  291.                     end;
  292.                 NextTiffIFD := 0;
  293.                 case WhatToOpen of
  294.                     OpenImage:  begin
  295.                             err := SetFPos(f, fsFromStart, 0);
  296.                             ByteCount := 8;
  297.                             err := fsread(f, ByteCount, @TempHdr);
  298.                             if TempHdr.FileID = FileID8 then begin
  299.                                     HeaderOffset := 0;
  300.                                     PictureType := normal
  301.                                 end
  302.                             else begin
  303.                                     HeaderOffset := -1;
  304.                                     BlockMove(@TempHdr, @hdr, 8);
  305.                                     nlines := hdr[1] + hdr[2] * 256;
  306.                                     PixelsPerLine := hdr[3] + hdr[4] * 256;
  307.                                     PictureType := PDP11;
  308.                                 end;
  309.                             ImageDataOffset := 512;
  310.                         end;
  311.                     OpenMCID:  begin
  312.                             err := SetFPos(f, fsFromStart, 0);
  313.                             ByteCount := 4;
  314.                             err := fsread(f, ByteCount, @hdr);
  315.                             PixelsPerLine := hdr[1] + hdr[2] * 256 + 1;
  316.                             if PixelsPerLine > MaxLine then begin
  317.                                     beep;
  318.                                     PixelsPerLine := MaxLine;
  319.                                 end;
  320.                             nlines := hdr[3] + hdr[4] * 256 + 1;
  321.                             PictureType := imported;
  322.                             LUTMode := grayscale;
  323.                             HeaderOffset := -1;
  324.                             ImageDataOffset := 4;
  325.                         end;
  326.                     OpenCustom:  begin
  327.                             if macro then begin
  328.                                     err := GetEof(f, FileSize);
  329.                                     if (ImportCustomOffset + LongInt(ImportCustomWidth) * ImportCustomHeight) > FileSize then begin
  330.                                             macro := false;
  331.                                             OpenHeader := false;
  332.                                             exit(OpenHeader)
  333.                                         end;
  334.                                 end;
  335.                             PixelsPerLine := ImportCustomWidth;
  336.                             nlines := ImportCustomHeight;
  337.                             PictureType := imported;
  338.                             HeaderOffset := -1;
  339.                             ImageDataOffset := ImportCustomOffset;
  340.                         end;
  341.                     OpenPICT2:  begin
  342.                             err := SetFPos(f, fsFromStart, 0);
  343.                             ByteCount := 8;
  344.                             err := fsread(f, ByteCount, @TempHdr);
  345.                             if TempHdr.FileID = FileID8 then
  346.                                 HeaderOffset := 0
  347.                             else
  348.                                 HeaderOffset := -1;
  349.                             PictureType := PictFile;
  350.                             if not UseExistingLUT then
  351.                                 LutMode := ColorLut;
  352.                             ImageDataOffset := 512;
  353.                         end;
  354.                     OpenTIFF:  begin
  355.                             if not OpenTiffHeader(f, DirOffset) then begin
  356.                                     OpenHeader := false;
  357.                                     exit(OpenHeader)
  358.                                 end;
  359.                             if not OpenTiffDirectory(f, DirOffset, TiffInfo) then begin
  360.                                     OpenHeader := false;
  361.                                     exit(OpenHeader)
  362.                                 end;
  363.                             with TiffInfo do begin
  364.                                     PictureType := TiffFile;
  365.                                     PixelsPerLine := width;
  366.                                     nlines := height;
  367.                                     if BitsPerPixel = 4 then
  368.                                         PictureType := FourBitTiff;
  369.                                     ImageDataOffset := OffsetToData;
  370.                                     if ZeroIsBlack and (PictureType <> FourBitTIFF) then
  371.                                         PictureType := InvertedTiff;
  372.                                     if resolution > 0.0 then begin
  373.                                             case ResUnits of
  374.                                                 tNoUnits: 
  375.                                                     GetUnits(14); {pixels}
  376.                                                 tCentimeters: 
  377.                                                     GetUnits(8);
  378.                                                 tInches: 
  379.                                                     GetUnits(11);
  380.                                             end;
  381.                                             RawSpatialScale := resolution;
  382.                                             xSpatialScale := resolution;
  383.                                             ySpatialScale := resolution;
  384.                                             PixelAspectRatio := 1.0;
  385.                                             ScaleMagnification := 1.0;
  386.                                             SpatiallyCalibrated := true;
  387.                                         end;
  388.                                     ColorMapOffset := OffsetToColorMap;
  389.                                     HeaderOffset := OffsetToImageHeader;
  390.                                     NextTiffIFD := NextIFD;
  391.                                 end;
  392.                             if not UseExistingLUT then
  393.                                 LutMode := Grayscale;
  394.                         end;
  395.                 end; {case}
  396.                 if HeaderOffset <> -1 then begin
  397.                         if not OpenImageHeader(f, fname, vnum) then begin
  398.                                 OpenHeader := false;
  399.                                 exit(OpenHeader)
  400.                             end
  401.                     end
  402.                 else if (ColorMapOffset > 0) and not UseExistingLUT then
  403.                     GetTiffColorMap(f);
  404.             end; {with}
  405.         OpenHeader := true;
  406.     end;
  407.  
  408.  
  409.     function SaveHeader (f, slines, sPixelsPerLine, vnum: integer; fname: str255; SavingSelection, SavingTIFF: boolean): OSErr;
  410.         var
  411.             TempHdr: PicHeader;
  412.             DummyHdr: array[1..128] of LongInt;
  413.             i: integer;
  414.             ByteCount: LongInt;
  415.             position: LongInt;
  416.             err: OSErr;
  417.             str: str255;
  418.     begin
  419.         with TempHdr, info^ do begin
  420.                 for i := 1 to 128 do
  421.                     DummyHdr[i] := 0;
  422.                 BlockMove(@DummyHdr, @TempHdr, HeaderSize);
  423.                 FileID := FileID8;
  424.                 hnlines := nlines;
  425.                 hPixelsPerLine := PixelsPerLine;
  426.                 hversion := version;
  427.                 hLUTMode := LUTMode;
  428.                 hOldLutMode := LutMode;
  429.                 hnColors := ncolors;
  430.                 hOldnColors := 0;
  431.                 if LutMode = Pseudocolor then begin
  432.                         hOldLutMode := ColorLut;
  433.                         if (ColorTable = CustomTable) and (ncolors <= 32) then
  434.                             for i := 0 to nColors - 1 do begin
  435.                                     hr[i] := RedLUT[i];
  436.                                     hg[i] := GreenLUT[i];
  437.                                     hb[i] := BlueLUT[i];
  438.                                 end;
  439.                     end;
  440.                 hColorStart := ColorStart;
  441.                 hColorEnd := ColorEnd;
  442.                 hFill1 := FillColor1;
  443.                 hFill2 := FillColor2;
  444.                 hTable := ColorTable;
  445.                 hInvertedTable := InvertedColorTable;
  446.                 hOldColorStart := 255 - ColorEnd;
  447.                 if nColors > 0 then
  448.                     hColorWidth := (ColorEnd - ColorStart) div nColors
  449.                 else
  450.                     hColorWidth := 1;
  451.                 hnExtraColors := nExtraColors;
  452.                 hExtraColors := ExtraColors;
  453.                 hForegroundIndex := ForegroundIndex;
  454.                 hBackgroundIndex := BackgroundIndex;
  455.                 hRawSpatialScale := RawSpatialScale;
  456.                 hScaleMagnification := ScaleMagnification;
  457.                 hPixelAspectRatio := PixelAspectRatio;
  458.                 hUnitsID := ord(UnitsID) + 5;
  459.                 FindPoints(hp1x, hp1y, hp2x, hp2y);
  460.                 if not DensityCalibrated then
  461.                     hnCoefficients := 0
  462.                 else
  463.                     hnCoefficients := nCoefficients;
  464.                 hfit := fit;
  465.                 hCoeff := Coefficient;
  466.                 hZeroClip := ZeroClip;
  467.                 hUM := UnitOfMeasure;
  468.                 hBinaryPic := BinaryPic;
  469.                 hSliceStart := SliceStart;
  470.                 hSliceEnd := SliceEnd;
  471.                 if StackInfo <> nil then
  472.                     with StackInfo^ do begin
  473.                             hNSlices := nSlices;
  474.                             hSliceSpacing := SliceSpacing;
  475.                             hCurrentSlice := CurrentSlice;
  476.                             hLoopTime := LoopTime;
  477.                         end
  478.                 else begin
  479.                         hNSlices := 0;
  480.                         hSliceSpacing := 0.0;
  481.                         hCurrentSlice := 0;
  482.                         hLoopTime := 0.0;
  483.                     end;
  484.                 ByteCount := SizeOf(TempHdr);
  485.                 if ByteCount <> HeaderSize then begin
  486.                         NumToString(ByteCount, str);
  487.                         PutMessage('Internal error check: header size is incorrect.');
  488.                         ExitToShell;
  489.                     end;
  490.                 if SavingSelection then begin
  491.                         hnlines := slines;
  492.                         hPixelsPerLine := sPixelsPerLine;
  493.                     end;
  494.                 err := fswrite(f, ByteCount, @TempHdr);
  495.                 SaveHeader := IOCheck(err);
  496.             end; {with}
  497.     end;
  498.  
  499.  
  500.     procedure PackLines;
  501.   {For odd width images, removes the extra bytes at the end of each line required to make RowBytes even.}
  502.         var
  503.             i: integer;
  504.             SrcPtr, DstPtr: ptr;
  505.     begin
  506.         with info^ do begin
  507.                 SrcPtr := ptr(ord4(PicBaseAddr) + BytesPerRow);
  508.                 DstPtr := ptr(ord4(PicBaseAddr) + PixelsPerLine);
  509.                 for i := 1 to nlines - 1 do begin
  510.                         BlockMove(SrcPtr, DstPtr, PixelsPerLine);
  511.                         SrcPtr := ptr(ord4(SrcPtr) + BytesPerRow);
  512.                         DstPtr := ptr(ord4(DstPtr) + PixelsPerLine);
  513.                     end;
  514.             end;
  515.     end;
  516.  
  517.  
  518.     procedure UnpackLines;
  519.   {For odd width images, adds an extra byte to each line so RowBytes is even.}
  520.         var
  521.             i: integer;
  522.             SrcPtr, DstPtr: ptr;
  523.     begin
  524.         with info^ do begin
  525.                 SrcPtr := ptr(ord4(PicBaseAddr) + LongInt(nlines - 1) * PixelsPerLine);
  526.                 DstPtr := ptr(ord4(PicBaseAddr) + LongInt(nlines - 1) * BytesPerRow);
  527.                 for i := 1 to nlines - 1 do begin
  528.                         BlockMove(SrcPtr, DstPtr, PixelsPerLine);
  529.                         SrcPtr := ptr(ord4(SrcPtr) - PixelsPerLine);
  530.                         DstPtr := ptr(ord4(DstPtr) - BytesPerRow);
  531.                     end;
  532.             end;
  533.     end;
  534.  
  535.  
  536.     function WriteSlices (f: integer): integer;
  537.         var
  538.             ByteCount, SelectionSize: LongInt;
  539.             i, err, SaveCS: integer;
  540.     begin
  541.         with info^, Info^.StackInfo^ do begin
  542.                 SaveCS := CurrentSlice;
  543.                 for i := 1 to nSlices do begin
  544.                         CurrentSlice := i;
  545.                         SelectSlice(CurrentSlice);
  546.                         UpdateTitleBar;
  547.                         ByteCount := ImageSize;
  548.                         if odd(PixelsPerLine) then
  549.                             PackLines;
  550.                         err := fswrite(f, ByteCount, PicBaseAddr);
  551.                         if odd(PixelsPerLine) then
  552.                             UnpackLines;
  553.                         if err <> 0 then
  554.                             leave;
  555.                     end;
  556.                 CurrentSlice := SaveCS;
  557.                 SelectSlice(CurrentSlice);
  558.                 UpdateTitleBar;
  559.                 WriteSlices := err;
  560.             end;
  561.     end;
  562.  
  563.  
  564.     function SaveTiffFile (fname: str255; vnum: integer; slines, sPixelsPerLine: integer; SavingSelection: boolean): boolean;
  565.         var
  566.             f, err, i, width, height: integer;
  567.             HdrSize, ByteCount, ctabSize, StackTiffDirSize, ImageDataSize: LongInt;
  568.             TheInfo: FInfo;
  569.             MCIDHeader: packed array[1..4] of byte;
  570.             SaveColorMap: boolean;
  571.     begin
  572.         SaveTiffFile := false;
  573.         ShowWatch;
  574.         err := fsopen(fname, vNum, f);
  575.         if IOCheck(err) <> 0 then
  576.             exit(SaveTiffFile);
  577.         with Info^ do begin
  578.                 SaveColorMap := (LutMode <> Grayscale) and (SaveAsWhat <> asRawData);
  579.                 if SaveAsWhat = SaveAsMCID then begin
  580.                         if SavingSelection then begin
  581.                                 width := sPixelsPerLine;
  582.                                 height := slines;
  583.                             end
  584.                         else begin
  585.                                 width := PixelsPerLine;
  586.                                 height := nLines;
  587.                             end;
  588.                         MCIDHeader[1] := (width - 1) mod 256;
  589.                         MCIDHeader[2] := (width - 1) div 256;
  590.                         MCIDHeader[3] := (height - 1) mod 256;
  591.                         MCIDHeader[4] := (height - 1) div 256;
  592.                         ByteCount := 4;
  593.                         err := fswrite(f, ByteCount, @MCIDHeader);
  594.                     end;
  595.                 HeaderOffset := TiffDirSize;
  596.                 ImageDataOffset := TiffDirSize + HeaderSize;
  597.                 if SaveColorMap then
  598.                     ctabSize := SizeOf(TiffColorMapType)
  599.                 else
  600.                     ctabSize := 0;
  601.                 StackTiffDirSize := 0;
  602.                 if SavingSelection then
  603.                     ImageDataSize := LongInt(slines) * sPixelsPerLine
  604.                 else if StackInfo <> nil then begin
  605.                         ImageDataSize := ImageSize * StackInfo^.nSlices;
  606.                         StackTiffDirSize := SizeOf(StackIFDType) * (StackInfo^.nSlices - 1)
  607.                     end
  608.                 else
  609.                     ImageDataSize := ImageSize;
  610.                 if (SaveAsWhat <> asRawData) and (SaveAsWhat <> SaveAsMCID) then begin
  611.                         if SaveTiffDir(f, slines, sPixelsPerLine, SavingSelection, ctabSize, ImageDataSize) <> NoErr then begin
  612.                                 err := fsclose(f);
  613.                                 err := FSDelete(fname, vnum);
  614.                                 exit(SaveTiffFile)
  615.                             end;
  616.                         err := SetFPos(f, FSFromStart, TiffDirSize);
  617.                         if SaveHeader(f, slines, sPixelsPerLine, vnum, fname, SavingSelection, true) <> NoErr then begin
  618.                                 err := fsclose(f);
  619.                                 err := FSDelete(fname, vnum);
  620.                                 exit(SaveTiffFile)
  621.                             end;
  622.                     end;
  623.                 if SaveAsWhat = SaveAsMCID then
  624.                     KillRoi;
  625.                 if SavingSelection then begin
  626.                         ByteCount := ImageDataSize;
  627.                         err := fswrite(f, ByteCount, UndoBuf);
  628.                         SetupUndo; {Needed for drawing roi outline}
  629.                     end
  630.                 else if StackInfo <> nil then
  631.                     err := WriteSlices(f)
  632.                 else begin
  633.                         ByteCount := ImageDataSize;
  634.                         if odd(PixelsPerLine) then
  635.                             PackLines;
  636.                         err := fswrite(f, ByteCount, PicBaseAddr);
  637.                         if odd(PixelsPerLine) then
  638.                             UnpackLines;
  639.                     end;
  640.                 if SaveAsWhat = SaveAsMCID then
  641.                     InvertPic;
  642.                 if IOCheck(err) <> 0 then begin
  643.                         err := fsclose(f);
  644.                         err := FSDelete(fname, vnum);
  645.                         exit(SaveTiffFile)
  646.                     end;
  647.                 if SaveAsWhat = asRawData then
  648.                     HdrSize := 0
  649.                 else if SaveAsWhat = SaveAsMCID then begin
  650.                         HdrSize := 4;
  651.                         SaveAsWhat := asRawData;
  652.                     end
  653.                 else
  654.                     HdrSize := HeaderSize + TiffDirSize;
  655.                 if SaveColorMap then
  656.                     SaveTiffColorMap(f, ImageDataSize);
  657.                 if StackTiffDirSize > 0 then
  658.                     err := WriteExtraTiffIFDs(f, ImageDataSize, cTabSize);
  659.                 err := SetEOF(f, HdrSize + ImageDataSize + ctabSize + StackTiffDirSize);
  660.                 err := fsclose(f);
  661.                 err := GetFInfo(fname, vnum, TheInfo);
  662.                 if TheInfo.fdCreator <> 'Imag' then begin
  663.                         TheInfo.fdCreator := 'Imag';
  664.                         err := SetFInfo(fname, vnum, TheInfo);
  665.                     end;
  666.                 if SaveAsWhat = asRawData then begin
  667.                         TheInfo.fdType := 'RawD';
  668.                         err := SetFInfo(fname, vnum, TheInfo);
  669.                     end
  670.                 else if TheInfo.fdType <> 'TIFF' then begin
  671.                         TheInfo.fdType := 'TIFF';
  672.                         err := SetFInfo(fname, vnum, TheInfo);
  673.                     end;
  674.                 err := FlushVol(nil, vNum);
  675.                 if not SavingSelection then begin
  676.                         if (PictureType <> BlankField) and (PictureType <> QuickCaptureType) and (PictureType <> ScionType) and (SaveAsWhat <> asRawData) then begin
  677.                                 PictureType := TiffFile;
  678.                                 title := fname;
  679.                                 vref := vnum;
  680.                                 if StackInfo <> nil then begin
  681.                                         UpdateTitleBar;
  682.                                         revertable := true;
  683.                                     end;
  684.                             end;
  685.                     end;
  686.                 if SaveAsWhat <> asRawData then
  687.                     Changes := false;
  688.             end; {with}
  689.         SaveTiffFile := true;
  690.     end;
  691.  
  692.  
  693.  
  694.  
  695.     procedure UpdateWindowsMenuItem (PicSize: LongInt; title: str255; PicNum: integer);
  696.         var
  697.             str: str255;
  698.     begin
  699.         NumToString(PicSize div 1024, str);
  700.         str := concat(title, '  ', str, 'K');
  701.         SetItem(WindowsMenuH, PicNum + WindowsMenuItems, str);
  702.     end;
  703.  
  704.  
  705.     procedure SaveAsTIFF (fname: str255; RefNum: integer; slines, sPixelsPerLine: integer; SavingSelection: boolean);
  706.         var
  707.             err: integer;
  708.             TheInfo: FInfo;
  709.             replacing, ok: boolean;
  710.             name: str255;
  711.     begin
  712.         err := GetFInfo(fname, RefNum, TheInfo);
  713.         case err of
  714.             NoErr: 
  715.                 with TheInfo do begin
  716.                         if (fdType <> 'TIFF') and (fdType <> 'PICT') and (fdType <> 'IPIC') and (fdType <> 'RawD') and (fdType <> 'PICS') then begin
  717.                                 TypeMismatch(fname);
  718.                                 exit(SaveAsTIFF)
  719.                             end;
  720.                         replacing := true;
  721.                     end;
  722.             FNFerr:  begin
  723.                     if SaveAsWhat = asRawData then
  724.                         err := create(fname, RefNum, 'Imag', 'RawD')
  725.                     else
  726.                         err := create(fname, RefNum, 'Imag', 'TIFF');
  727.                     if IOCheck(err) <> 0 then
  728.                         exit(SaveAsTIFF);
  729.                     replacing := false;
  730.                 end;
  731.             otherwise
  732.                 if IOCheck(err) <> 0 then
  733.                     exit(SaveAsTIFF);
  734.         end;
  735.         if replacing then
  736.             if not RoomForFile(fname, RefNum, slines, sPixelsPerLine, SavingSelection) then
  737.                 exit(SaveAsTIFF);
  738.         ok := SaveTiffFile(fname, RefNum, slines, sPixelsPerLine, SavingSelection);
  739.         if ok then
  740.             with info^ do
  741.                 if StackInfo <> nil then
  742.                     UpdateWindowsMenuItem(ImageSize * StackInfo^.nSlices, title, PicNum)
  743.                 else
  744.                     UpdateWindowsMenuItem(ImageSize, title, PicNum);
  745.         with info^ do
  746.             if SavingSelection and Replacing and (PictureType <> BlankField) and (PictureType <> QuickCaptureType) and (PictureType <> ScionType) then
  747.                 PictureType := Leftover;
  748.     end;
  749.  
  750.  
  751.     function SavePICTFile (fname: str255; vnum: integer; SavingSelection, NewFile: boolean): boolean;
  752.         var
  753.             f, err, i, v: integer;
  754.             ByteCount, PICTSize: LongInt;
  755.             PicH: PicHandle;
  756.             fRect, frect2: rect;
  757.             tPort: GrafPtr;
  758.             TheInfo: FInfo;
  759.             SaveInfoRec: PicInfo;
  760.             HeaderSaved: boolean;
  761.  
  762.         procedure Abort;
  763.         begin
  764.             err := fsclose(f);
  765.             if NewFile then
  766.                 err := FSDelete(fname, vnum);
  767.             DisposHandle(handle(PicH));
  768.             exit(SavePICTFile)
  769.         end;
  770.  
  771.     begin
  772.         with info^ do begin
  773.                 if OpPending then
  774.                     KillRoi;
  775.                 SavePICTFile := false;
  776.                 ShowWatch;
  777.                 GetPort(tPort);
  778.                 if SavingSelection then
  779.                     fRect := RoiRect
  780.                 else
  781.                     SetRect(fRect, 0, 0, PixelsPerLine, nlines);
  782.                 with frect do
  783.                     SetRect(frect2, 0, 0, right - left, bottom - top);
  784.                 with osPort^ do begin
  785.                         SetPort(GrafPtr(osPort));
  786.                         pmForeColor(BlackIndex);
  787.                         pmBackColor(WhiteIndex);
  788.                         if OldSystem then begin  {Work around for Palette Manager bug in Systems before 6.0.5.}
  789.                                 RGBForeColor(BlackRGB);
  790.                                 RGBBackColor(WhiteRGB);
  791.                             end;
  792.                         ClipRect(PicRect);
  793.                         LoadLUT(cTable);  {Restore look-up table in case it has changed.}
  794.                         PicH := OpenPicture(fRect2);
  795.                         hlock(handle(PortPixMap));
  796.                         CopyBits(BitMapHandle(PortPixMap)^^, BitMapHandle(PortPixMap)^^, frect, frect2, SrcCopy, nil);
  797.                         hunlock(handle(PortPixMap));
  798.                         ClosePicture;
  799.                         pmForeColor(ForegroundIndex);
  800.                         pmBackColor(BackgroundIndex);
  801.                     end;
  802.                 SetPort(tPort);
  803.                 PICTSize := GetHandleSize(handle(PicH));
  804.                 if PICTSize <= 10 then begin
  805.                         PutMessage('Sorry, but there is not enough memory available to save this PICT file. Try closing some windows, or save as TIFF.');
  806.                         if NewFile then
  807.                             err := FSDelete(fname, vnum);
  808.                         DisposHandle(handle(PicH));
  809.                         exit(SavePICTFile)
  810.                     end;
  811.                 err := fsopen(fname, vnum, f);
  812.                 err := SetFPos(f, FSFromStart, 0);
  813.                 SaveInfoRec := Info^;
  814.                 if (LutMode = GrayScale) or (LutMode = CustomGrayScale) then begin
  815.                         nColors := 256;
  816.                         ColorStart := 0;
  817.                         ColorEnd := 255;
  818.                         LUTMode := Grayscale;
  819.                         IdentityFunction := true;
  820.                     end;
  821.                 HeaderSaved := SaveHeader(f, 0, 0, vnum, fname, SavingSelection, false) = 0;
  822.                 Info^ := SaveInfoRec;
  823.                 if not HeaderSaved then
  824.                     abort;
  825.                 err := fswrite(f, PICTSize, pointer(PicH^));
  826.                 if IOCheck(err) <> 0 then
  827.                     abort;
  828.                 DisposHandle(handle(PicH));
  829.                 ByteCount := PICTSize + HeaderSize;
  830.                 err := SetEOF(f, ByteCount);
  831.                 err := fsclose(f);
  832.                 err := GetFInfo(fname, vnum, TheInfo);
  833.                 if TheInfo.fdCreator <> 'Imag' then begin
  834.                         TheInfo.fdCreator := 'Imag';
  835.                         err := SetFInfo(fname, vnum, TheInfo);
  836.                     end;
  837.                 if TheInfo.fdType <> 'PICT' then begin
  838.                         TheInfo.fdType := 'PICT';
  839.                         err := SetFInfo(fname, vnum, TheInfo);
  840.                     end;
  841.                 err := FlushVol(nil, vnum);
  842.                 if not SavingSelection then begin
  843.                         if (PictureType <> BlankField) and (PictureType <> QuickCaptureType) and (PictureType <> ScionType) and (PictureType <> NullPicture) then begin
  844.                                 PictureType := PictFile;
  845.                                 title := fname;
  846.                                 UpdateTitleBar;
  847.                                 vref := vnum;
  848.                                 revertable := true;
  849.                             end;
  850.                         Changes := false;
  851.                     end;
  852.             end; {with}
  853.         SavePICTFile := true;
  854.     end;
  855.  
  856.  
  857.     procedure SaveAsPICT (fname: str255; RefNum: integer; SavingSelection: boolean);
  858.         var
  859.             f, err, i: integer;
  860.             where: Point;
  861.             TheInfo: FInfo;
  862.             replacing, ok: boolean;
  863.             name: str255;
  864.     begin
  865.         err := GetFInfo(fname, RefNum, TheInfo);
  866.         case err of
  867.             NoErr: 
  868.                 with TheInfo do begin
  869.                         if (fdType <> 'TIFF') and (fdType <> 'PICT') and (fdType <> 'IPIC') then begin
  870.                                 TypeMismatch(fname);
  871.                                 exit(SaveAsPICT)
  872.                             end;
  873.                         replacing := true;
  874.                     end;
  875.             FNFerr:  begin
  876.                     err := create(fname, RefNum, 'Imag', 'PICT');
  877.                     if IOCheck(err) <> 0 then
  878.                         exit(SaveAsPICT);
  879.                     replacing := false;
  880.                 end;
  881.             otherwise
  882.                 if IOCheck(err) <> 0 then
  883.                     exit(SaveAsPICT);
  884.         end;
  885.         ok := SavePICTFile(fname, RefNum, SavingSelection, not Replacing);
  886.         if ok then
  887.             with info^ do
  888.                 UpdateWindowsMenuItem(ImageSize, title, PicNum);
  889.         with info^ do
  890.             if SavingSelection and replacing and (PictureType <> BlankField) and (PictureType <> QuickCaptureType) and (PictureType <> ScionType) then
  891.                 PictureType := Leftover;
  892.     end;
  893.  
  894.  
  895.     procedure SaveSelection (fname: str255; RefNum: integer; SaveAsSameType: boolean);
  896.         var
  897.             size, offset: LongInt;
  898.             i, slines, spixelsPerLine, hstart, vstart: integer;
  899.             src, dst: ptr;
  900.     begin
  901.         if NoSelection or NotRectangular or NotInBounds then
  902.             exit(SaveSelection);
  903.         if OpPending then
  904.             KillRoi;
  905.         with info^ do begin
  906.                 with RoiRect do begin
  907.                         sPixelsPerLine := right - left;
  908.                         if odd(sPixelsPerLine) and (left + sPixelsPerLine < PicRect.right) and (SaveAsWhat <> asRawData) then
  909.                             sPixelsPerLine := sPixelsPerLine + 1;
  910.                         slines := bottom - top;
  911.                         size := LongInt(slines) * sPixelsPerLine;
  912.                         hstart := left;
  913.                         vstart := top;
  914.                     end;
  915.                 if (PictureType <> PictFile) or not SaveAsSameType then begin
  916.                         if size > UndoBufSize then begin
  917.                                 PutMessage('There is not enough memory available to save the selection');
  918.                                 exit(SaveSelection)
  919.                             end;
  920.                         offset := LongInt(vstart) * BytesPerRow + hstart;
  921.                         src := ptr(ord4(PicBaseAddr) + offset);
  922.                         dst := UndoBuf;
  923.                         for i := 0 to slines - 1 do begin
  924.                                 BlockMove(src, dst, sPixelsPerLine);
  925.                                 src := ptr(ord4(src) + BytesPerRow);
  926.                                 dst := ptr(ord4(dst) + sPixelsPerLine);
  927.                             end;
  928.                     end;
  929.                 if (PictureType = PictFile) and SaveAsSameType and (SaveAsWhat <> asRawData) then
  930.                     SaveAsPICT(fname, RefNum, true)
  931.                 else
  932.                     SaveAsTIFF(fname, RefNum, slines, sPixelsPerLine, true);
  933.             end;
  934.     end;
  935.  
  936.  
  937.     procedure SaveAsText (fname: str255; RefNum: integer);
  938.         var
  939.             err, f: integer;
  940.             TheInfo: FInfo;
  941.             ByteCount: LongInt;
  942.     begin
  943.         err := GetFInfo(fname, RefNum, TheInfo);
  944.         case err of
  945.             NoErr: 
  946.                 if TheInfo.fdType <> 'TEXT' then begin
  947.                         TypeMismatch(fname);
  948.                         exit(SaveAsText)
  949.                     end;
  950.             FNFerr:  begin
  951.                     err := create(fname, RefNum, 'MSWD', 'TEXT');
  952.                     if IOCheck(err) <> 0 then
  953.                         exit(SaveAsText);
  954.                 end;
  955.             otherwise
  956.                 if IOCheck(err) <> 0 then
  957.                     exit(SaveAsTExt)
  958.         end;
  959.         ShowWatch;
  960.         err := fsopen(fname, RefNum, f);
  961.         if IOCheck(err) <> 0 then
  962.             exit(SaveAsText);
  963.         ByteCount := TextBufSize;
  964.         err := fswrite(f, ByteCount, ptr(TextBufP));
  965.         if IOCheck(err) <> 0 then
  966.             exit(SaveAsText);
  967.         err := SetEof(f, ByteCount);
  968.         err := fsclose(f);
  969.         err := FlushVol(nil, RefNum);
  970.         if WhatsOnClip = TextOnClip then
  971.             WhatsOnClip := Nothing;
  972.     end;
  973.  
  974.  
  975.     procedure SaveAsPICS (fname: str255; fRefNum: integer);
  976.         const
  977.             rErr = 'Error Saving PICS file.';
  978.         var
  979.             err: OSErr;
  980.             TheInfo: FInfo;
  981.             replacing: boolean;
  982.             rRefNum, i, SaveCS: integer;
  983.             frect: rect;
  984.             PicH: array[1..MaxSlices] of PicHandle;
  985.             MinFreeRequired: LongInt;
  986.     begin
  987.         with info^, Info^.StackInfo^ do begin
  988.                 if StackInfo = nil then begin
  989.                         PutMessage('Only Stacks can be saved in PICS format.');
  990.                         SaveAsWhat := asTiff;
  991.                         exit(SaveAsPICS);
  992.                     end;
  993.                 if ImageSize > MinFree then
  994.                     MinFreeRequired := ImageSize
  995.                 else
  996.                     MinFreeRequired := MinFree;
  997.                 if MaxBlock < MinFreeRequired then begin
  998.                         PutMessage('Not enough memory available to save in PICS format.');
  999.                         exit(SaveAsPICS);
  1000.                     end;
  1001.                 err := GetFInfo(fname, fRefNum, TheInfo);
  1002.                 if err = NoErr then
  1003.                     with TheInfo do begin
  1004.                             if (fdType <> 'TIFF') and (fdType <> 'PICT') and (fdType <> 'PICS') then begin
  1005.                                     TypeMismatch(fname);
  1006.                                     exit(SaveAsPICS)
  1007.                                 end;
  1008.                             err := FSDelete(fname, fRefNum);
  1009.                         end;
  1010.                 ShowWatch;
  1011.                 err := SetVol(nil, fRefNum);
  1012.                 CreateResFile(fname);
  1013.                 if ResError <> NoErr then
  1014.                     exit(SaveAsPICS);
  1015.                 rRefNum := OpenResFile(fname);
  1016.                 SaveCS := CurrentSlice;
  1017.                 SetPort(GrafPtr(osPort));
  1018.                 with PicRect do
  1019.                     SetRect(frect, 0, 0, right - left, bottom - top);
  1020.                 ClipRect(frect);
  1021.                 LoadLUT(ctable);
  1022.                 pmForeColor(BlackIndex);
  1023.                 pmBackColor(WhiteIndex);
  1024.                 if OldSystem then begin
  1025.                         RGBForeColor(BlackRGB);
  1026.                         RGBBackColor(WhiteRGB);
  1027.                     end;
  1028.                 for i := 1 to nSlices do begin
  1029.                         CurrentSlice := i;
  1030.                         SelectSlice(CurrentSlice);
  1031.                         UpdateTitleBar;
  1032.                         PicH[i] := OpenPicture(frect);
  1033.                         with osPort^ do begin
  1034.                                 hlock(handle(portPixMap));
  1035.                                 CopyBits(BitMapHandle(portPixMap)^^, BitMapHandle(portPixMap)^^, PicRect, frect, SrcCopy, nil);
  1036.                                 hunlock(handle(portPixMap));
  1037.                             end;
  1038.                         ClosePicture;
  1039.                         if (PicH[i] = nil) or ((PicH[i] <> nil) and (GetHandleSize(handle(PicH[i])) <= 10)) then begin
  1040.                                 PutMessage(rErr);
  1041.                                 leave;
  1042.                             end;
  1043.                         AddResource(handle(PicH[i]), 'PICT', i - 1 + 128, '');
  1044.                         if ResError <> NoErr then begin
  1045.                                 PutMessage(rErr);
  1046.                                 leave;
  1047.                             end;
  1048.                         WriteResource(handle(PicH[i]));
  1049.                         ReleaseResource(handle(PicH[i]));
  1050.                         if ResError <> NoErr then begin
  1051.                                 PutMessage(rErr);
  1052.                                 leave;
  1053.                             end;
  1054.                     end; {for}
  1055.                 CurrentSlice := SaveCS;
  1056.                 SelectSlice(CurrentSlice);
  1057.                 title := fname;
  1058.                 PictureType := PicsFile;
  1059.                 UpdateTitleBar;
  1060.                 CloseResFile(rRefNum);
  1061.                 if ResError <> NoErr then
  1062.                     PutMessage(rErr);
  1063.                 err := GetFInfo(fname, fRefNum, TheInfo);
  1064.                 TheInfo.fdType := 'PICS';
  1065.                 TheInfo.fdCreator := 'Imag';
  1066.                 err := SetFInfo(fname, fRefNum, TheInfo);
  1067.                 err := FlushVol(nil, fRefNum);
  1068.                 UpdateWindowsMenuItem(ImageSize, title, PicNum);
  1069.                 pmForeColor(ForegroundIndex);
  1070.                 pmBackColor(BackgroundIndex);
  1071.             end; {with}
  1072.     end;
  1073.  
  1074.  
  1075. {$POP}
  1076.  
  1077.  
  1078.     function SuggestedName: str255;
  1079.         var
  1080.             name: str255;
  1081.     begin
  1082.         case SaveAsWhat of
  1083.             asTiff, asPict, asMacPaint, asRawData, asPICS:  begin
  1084.                     name := info^.title;
  1085.                     if name = 'Camera' then
  1086.                         name := 'Untitled';
  1087.                     SuggestedName := name;
  1088.                 end;
  1089.             AsPalette: 
  1090.                 SuggestedName := 'Palette';
  1091.             AsOutline: 
  1092.                 SuggestedName := 'Outline';
  1093.         end;
  1094.     end;
  1095.  
  1096.  
  1097.     function SaveAsHook (item: integer; theDialog: DialogPtr): integer;
  1098.         const
  1099.             EditTextID = 7;
  1100.             TiffID = 9;
  1101.             OutlineID = 14;
  1102.         var
  1103.             i: integer;
  1104.             fname: str255;
  1105.             NameEdited: boolean;
  1106.     begin
  1107.         if item = -1 then {Initialize}
  1108.             SetDialogItem(theDialog, TiffID + ord(SaveAsWhat), 1);
  1109.         fname := GetDString(theDialog, EditTextID);
  1110.         NameEdited := fname <> SuggestedName;
  1111.         if (item >= TiffID) and (item <= OutlineID) then begin
  1112.                 SaveAsWhat := SaveAsWhatType(item - TiffID);
  1113.                 if not NameEdited then begin
  1114.                         SetDString(theDialog, EditTextID, SuggestedName);
  1115.                         SelIText(theDialog, EditTextID, 0, 32767);
  1116.                     end;
  1117.                 for i := TiffID to OutlineID do
  1118.                     SetDialogItem(theDialog, i, 0);
  1119.                 SetDialogItem(theDialog, item, 1);
  1120.             end;
  1121.         SaveAsHook := item;
  1122.     end;
  1123.  
  1124.  
  1125.     procedure SaveAs (name: str255; RefNum: integer);
  1126.         const
  1127.             CustomDialogID = 60;
  1128.         var
  1129.             where: Point;
  1130.             reply: SFReply;
  1131.             isSelection: boolean;
  1132.             kind: integer;
  1133.     begin
  1134.         with info^ do begin
  1135.                 if SaveAllState = SaveAllStage2 then begin
  1136.                         name := title;
  1137.                         RefNum := SaveRefNum;
  1138.                         if SaveAsWhat = AsPalette then
  1139.                             SaveAsWhat := AsTiff;
  1140.                     end
  1141.                 else if (name = '') or (RefNum = 0) then begin
  1142.                         where.v := 50;
  1143.                         where.h := 50;
  1144.                         if (StackInfo = nil) and (SaveAsWhat = asPICS) then
  1145.                             SaveAsWhat := asTIFF;
  1146.                         if (StackInfo <> nil) and ((SaveAsWhat = asPICT) or (SaveAsWhat = asMacPaint)) then
  1147.                             SaveAsWhat := asTIFF;
  1148.                         if name = '' then
  1149.                             name := SuggestedName;
  1150.                         SFPPutFile(Where, 'Save as?', name, @SaveAsHook, reply, CustomDialogID, nil);
  1151.                         if not reply.good then begin
  1152.                                 SaveAllState := NoSaveAll;
  1153.                                 macro := false;
  1154.                                 exit(SaveAs);
  1155.                             end;
  1156.                         with reply do begin
  1157.                                 name := fname;
  1158.                                 RefNum := vRefNum;
  1159.                                 DefaultRefNum := RefNum;
  1160.                             end;
  1161.                     end;
  1162.                 if StackInfo <> nil then begin
  1163.                         KillRoi;
  1164.                         SaveAllState := NoSaveAll;
  1165.                         if not ((SaveAsWhat = asTIFF) or (SaveAsWhat = asPICS) or (SaveAsWhat = asPalette)) then begin
  1166.                                 PutMessage('Stacks can only be saved in TIFF or PICS format.');
  1167.                                 SaveAsWhat := asTIFF;
  1168.                                 exit(SaveAs);
  1169.                             end;
  1170.                     end;
  1171.                 isSelection := RoiShowing and (RoiType = RectRoi);
  1172.                 if SaveAllState = SaveAllStage1 then begin
  1173.                         SaveRefNum := RefNum;
  1174.                         SaveAllState := SaveAllStage2;
  1175.                     end;
  1176.                 case SaveAsWhat of
  1177.                     asTiff, asRawData: 
  1178.                         if isSelection then
  1179.                             SaveSelection(name, RefNum, false)
  1180.                         else
  1181.                             SaveAsTIFF(name, RefNum, 0, 0, false);
  1182.                     asPict: 
  1183.                         if isSelection then
  1184.                             SaveAsPICT(name, RefNum, true)
  1185.                         else
  1186.                             SaveAsPICT(name, RefNum, false);
  1187.                     asMacPaint: 
  1188.                         SaveAsMacPaint(name, RefNum);
  1189.                     asPICS: 
  1190.                         SaveAsPICS(name, RefNum);
  1191.                     AsPalette: 
  1192.                         SaveColorTable(name, RefNum);
  1193.                     AsOutline: 
  1194.                         SaveOutline(name, RefNum);
  1195.                 end; {case}
  1196.                 if (SaveAsWhat = asRawData) and (SaveAllState <> SaveAllStage2) then
  1197.                     SaveAsWhat := asTIFF;
  1198.             end; {with}
  1199.     end;
  1200.  
  1201.  
  1202.     procedure SaveFile;
  1203.         var
  1204.             fname: str255;
  1205.             size: LongInt;
  1206.             ok: boolean;
  1207.     begin
  1208.         if FrontWindow = ResultsWindow then begin
  1209.                 Export('', 0);
  1210.                 exit(SaveFile);
  1211.             end;
  1212.         if OpPending then
  1213.             KillRoi;
  1214.         with Info^ do begin
  1215.                 fname := title;
  1216.                 size := 0;
  1217.                 if PictureType = TiffFile then
  1218.                     ok := SaveTiffFile(fname, vref, 0, 0, false)
  1219.                 else if PictureType = PictFile then
  1220.                     ok := SavePICTFile(fname, vref, false, false)
  1221.                 else
  1222.                     SaveAs('', 0);
  1223.             end;
  1224.     end;
  1225.  
  1226.  
  1227.     function SaveChanges: integer;
  1228.         const
  1229.             yesID = 1;
  1230.             noID = 2;
  1231.             cancelID = 3;
  1232.         var
  1233.             id: integer;
  1234.             reply: SFReply;
  1235.     begin
  1236.         id := 0;
  1237.         if info^.changes then
  1238.             with info^ do begin
  1239.                     if CommandPeriod or MakingStack or (macro and ((MacroCommand = DisposeC) or (MacroCommand = DisposeAllC))) then begin
  1240.                             SaveChanges := ok;
  1241.                             exit(SaveChanges);
  1242.                         end;
  1243.                     ParamText(title, '', '', '');
  1244.                     InitCursor;
  1245.                     id := alert(600, nil);
  1246.                     if id = yesID then begin
  1247.                             SaveFile;
  1248.                             InitCursor;
  1249.                         end; {if yes}
  1250.                 end; {if changes}
  1251.         if (id = cancelID) or ((id = yesID) and (info^.changes)) then
  1252.             SaveChanges := cancel
  1253.         else
  1254.             SaveChanges := ok;
  1255.     end;
  1256.  
  1257.  
  1258.     function CloseAWindow (WhichWindow: WindowPtr): integer;
  1259.         var
  1260.             i, kind, n: integer;
  1261.             TempInfo: InfoPtr;
  1262.             SizeStr, str: str255;
  1263.             wp: ^WindowPtr;
  1264.             pcrect: rect;
  1265.     begin
  1266.         kind := WindowPeek(WhichWindow)^.WindowKind;
  1267.         CloseAWindow := ok;
  1268.         case kind of
  1269.             PicKind:  begin
  1270.                     Info := pointer(WindowPeek(WhichWindow)^.RefCon);
  1271.                     with Info^ do begin
  1272.                             if PicNum = 0 then begin
  1273.                                     beep;
  1274.                                     exit(CloseAWindow);
  1275.                                 end;
  1276.                             if SaveChanges = cancel then begin
  1277.                                     CloseAWindow := cancel;
  1278.                                     exit(CloseAWindow)
  1279.                                 end;
  1280.                             DelMenuItem(WindowsMenuH, PicNum + WindowsMenuItems);
  1281.                             for i := PicNum to nPics - 1 do begin
  1282.                                     PicWindow[i] := PicWindow[i + 1];
  1283.                                     TempInfo := pointer(WindowPeek(PicWindow[i])^.RefCon);
  1284.                                     TempInfo^.PicNum := i
  1285.                                 end;
  1286.                             if PictureType = QuickCaptureType then
  1287.                                 QuickCaptureInfo := nil;
  1288.                             if PictureType = BlankField then
  1289.                                 BlankFieldInfo := nil;
  1290.                             if PictureType = ScionType then
  1291.                                 ScionInfo := nil;
  1292.                             if StackInfo <> nil then begin
  1293.                                     with StackInfo^ do
  1294.                                         for i := 1 to nSlices do
  1295.                                             DisposHandle(PicBaseH[i]);
  1296.                                     DisposPtr(pointer(StackInfo));
  1297.                                 end
  1298.                             else begin
  1299.                                     if not MakingStack then
  1300.                                         DisposHandle(PicBaseHandle);
  1301.                                 end;
  1302.                             DisposeWindow(WhichWindow);
  1303.                             CloseCPort(osPort);
  1304.                             Dispose(osPort);
  1305.                             DisposeRgn(roiRgn);
  1306.                             nPics := nPics - 1;
  1307.                             OpPending := false;
  1308.                             isInsertionPoint := false;
  1309.                             DisposPtr(pointer(Info));
  1310.                             Info := NoInfo;
  1311.                             if (nPics = 0) and (not finished) then
  1312.                                 with info^ do begin
  1313.                                         LoadLUT(info^.cTable);
  1314.                                         if (LutMode = GrayScale) or (LutMode = CustomGrayScale) then
  1315.                                             DrawMap;
  1316.                                     end;
  1317.                             PicLeft := PicLeftBase;
  1318.                             PicTop := PicTopBase;
  1319.                         end;
  1320.                 end; {PicKind}
  1321.             HistoKind:  begin
  1322.                     DisposeWindow(HistoWindow);
  1323.                     HistoWindow := nil;
  1324.                     ContinuousHistogram := false;
  1325.                 end;
  1326.             ProfilePlotKind, CalibrationPlotKind:  begin
  1327.                     DisposeWindow(PlotWindow);
  1328.                     PlotWindow := nil;
  1329.                     KillPicture(PlotPICT);
  1330.                     PlotPICT := nil;
  1331.                 end;
  1332.             ResultsKind:  begin
  1333.                     DisposeWindow(ResultsWindow);
  1334.                     ResultsWindow := nil;
  1335.                     TEDispose(ListTE);
  1336.                 end;
  1337.             PasteControlKind:  begin
  1338.                     GetWindowRect(PasteControl, pcrect);
  1339.                     with pcrect do begin
  1340.                             PasteControlLeft := left;
  1341.                             PasteControlTop := top;
  1342.                         end;
  1343.                     DisposeWindow(PasteControl);
  1344.                     PasteControl := nil;
  1345.                     wp := pointer(GhostWindow);
  1346.                     wp^ := nil;
  1347.                 end;
  1348.         end; {case}
  1349.     end;
  1350.  
  1351.  
  1352.     procedure DoClose;
  1353.         var
  1354.             ignore: integer;
  1355.             fwptr: WindowPtr;
  1356.             kind: integer;
  1357.     begin
  1358.         fwptr := FrontWindow;
  1359.         kind := WindowPeek(fwptr)^.WindowKind;
  1360.         if (kind = PicKind) or (kind = ProfilePlotKind) or (kind = CalibrationPlotKind) or (kind = HistoKind) or (Kind = PasteControlKind) or (Kind = ResultsKind) then
  1361.             ignore := CloseAWindow(fwptr);
  1362.     end;
  1363.  
  1364.  
  1365.     procedure Read4BitTIFF (f: integer);
  1366.         var
  1367.             vloc, hloc, i: integer;
  1368.             ByteCount, count: LongInt;
  1369.             err: OSErr;
  1370.             UnpackedLine, PackedLine: LineType;
  1371.     begin
  1372.         with info^ do begin
  1373.                 if PixelsPerLine > MaxLine then
  1374.                     exit(Read4BitTIFF);
  1375.                 ByteCount := (PixelsPerLine + 1) div 2;
  1376.                 for vloc := 0 to nLines - 1 do begin
  1377.                         err := FSRead(f, ByteCount, @PackedLine);
  1378.                         i := 0;
  1379.                         for hloc := 0 to PixelsPerLine - 1 do
  1380.                             if odd(hloc) then begin
  1381.                                     UnpackedLine[hloc] := bsl(band(PackedLine[i], $F), 4);
  1382.                                     i := i + 1;
  1383.                                 end
  1384.                             else
  1385.                                 UnpackedLine[hloc] := band(PackedLine[i], $F0);
  1386.                         PutLine(0, vloc, PixelsPerLine, UnpackedLine);
  1387.                     end;
  1388.             end; {with}
  1389.     end;
  1390.  
  1391.  
  1392.     procedure Import16BitImage;
  1393.         type
  1394.             IntArrayType = packed array[0..5000000] of integer;
  1395.             IntArrayPtr = ^IntArrayType;
  1396.             PixelLUTType = packed array[0..65535] of Unsignedbyte;
  1397.             PixelLUTPtr = ^PixelLUTType;
  1398.         var
  1399.             line: LineType;
  1400.             IntArray: IntArrayPtr;
  1401.             i, j, value, min, max, tmin, tmax: LongInt;
  1402.             ScaleFactor: extended;
  1403.             hloc, vloc, wwidth, wheight, IntValue, SaveBytesPerRow: integer;
  1404.             tPort: GrafPtr;
  1405.             PixelLUT: PixelLUTPtr;
  1406.             FixedScale: boolean;
  1407.             str1, str2, str3: str255;
  1408.     begin
  1409.         with info^ do begin
  1410.                 if PixelsPerLine > MaxLine then
  1411.                     exit(Import16BitImage);
  1412.                 PixelLUT := PixelLUTPtr(NewPtr(SizeOf(PixelLUTType)));
  1413.                 if PixelLUT = nil then begin
  1414.                         PutMessage('Not enough memory to do 16 to 8-bit scaling.');
  1415.                         exit(Import16BitImage);
  1416.                     end;
  1417.                 if odd(PixelsPerLine) then begin
  1418.                         SaveBytesPerRow := BytesPerRow;
  1419.                         BytesPerRow := PixelsPerLine; {Needed to get PutLine to work.}
  1420.                     end;
  1421.                 IntArray := IntArrayPtr(PicBaseAddr);
  1422.                 min := 999999;
  1423.                 max := -999999;
  1424.                 for i := 0 to ImageSize - 1 do begin
  1425.                         if ImportSwapBytes then begin
  1426.                                 IntValue := IntArray^[i];
  1427.                                 swap2bytes(IntValue);
  1428.                                 IntArray^[i] := IntValue;
  1429.                             end;
  1430.                         value := IntArray^[i];
  1431.                         if (ImportCustomDepth = SixteenBitsUnsigned) and (value < 0) then
  1432.                             value := value + 65536;
  1433.                         if value > max then
  1434.                             max := value;
  1435.                         if value < min then
  1436.                             min := value;
  1437.                     end;
  1438.                 str1 := concat('min=', long2str(min), cr, 'max=', long2str(max));
  1439.                 str2 := '';
  1440.                 FixedScale := not ImportAutoScale;
  1441.                 if FixedScale then begin
  1442.                         tmin := round(ImportMin);
  1443.                         tmax := round(ImportMax);
  1444.                         if ((tmax - tmin) < 65536) and (tmin <= tmax) then begin
  1445.                                 min := tmin;
  1446.                                 max := tmax;
  1447.                                 str2 := concat(cr, 'fixed: ', long2str(min), '-', long2str(max));
  1448.                             end;
  1449.                     end;
  1450.                 ScaleFactor := 253.0 / (max - min);
  1451.                 RealToString(ScaleFactor, 1, 4, str3);
  1452.                 ShowMessage(concat(str1, str2, cr, 'scale factor= ', str3));
  1453.                 j := 0;
  1454.                 for i := min to max do begin
  1455.                         PixelLUT^[j] := round((i - min) * ScaleFactor + 1);
  1456.                         j := j + 1;
  1457.                     end;
  1458.                 i := 0;
  1459.                 for vloc := 0 to nlines - 1 do begin
  1460.                         for hloc := 0 to PixelsPerLine - 1 do begin
  1461.                                 value := IntArray^[i];
  1462.                                 if (ImportCustomDepth = SixteenBitsUnsigned) and (value < 0) then
  1463.                                     value := value + 65536;
  1464.                                 if FixedScale then begin
  1465.                                         if value < min then
  1466.                                             value := min;
  1467.                                         if value > max then
  1468.                                             value := max;
  1469.                                     end;
  1470.                                 line[hloc] := PixelLUT^[value - min];
  1471.                                 i := i + 1;
  1472.                             end;
  1473.                         PutLine(0, vloc, PixelsPerLine, line);
  1474.                     end;
  1475.                 if ImportCalibrate then begin
  1476.                         fit := StraightLine;
  1477.                         nCoefficients := 2;
  1478.                         coefficient[1] := max;
  1479.                         coefficient[2] := (min - max) / 255;
  1480.                         DensityCalibrated := true;
  1481.                         ZeroClip := false;
  1482.                         UpdateTitleBar;
  1483.                     end
  1484.                 else
  1485.                     DensityCalibrated := false;
  1486.                 FileDepth := ImportCustomDepth;
  1487.                 if odd(PixelsPerLine) then
  1488.                     BytesPerRow := SaveBytesPerRow;
  1489.                 DisposPtr(ptr(PixelLUT));
  1490.                 SetHandleSize(PicBaseHandle, PixMapSize);
  1491.             end; {with}
  1492.     end;
  1493.  
  1494.  
  1495.     procedure ReadStackSlices (f, nExtraImages: integer; var table: TiffIFDTable);
  1496.         var
  1497.             i, err, SaveCS: integer;
  1498.             h: handle;
  1499.             DataSize: LongInt;
  1500.     begin
  1501.         ShowMessage(CmdPeriodToStop);
  1502.         with info^ do begin
  1503.                 StackInfo := StackInfoPtr(NewPtr(SizeOf(StackInfoRec)));
  1504.                 if StackInfo = nil then
  1505.                     exit(ReadStackSlices);
  1506.             end;
  1507.         with info^, info^.StackInfo^ do begin
  1508.                 nSlices := nExtraImages + 1;
  1509.                 CurrentSlice := TempStackInfo.CurrentSlice;
  1510.                 if (CurrentSlice < 1) or (CurrentSlice > nSlices) then
  1511.                     CurrentSlice := 1;
  1512.                 SliceSpacing := TempStackInfo.SliceSpacing;
  1513.                 LoopTime := TempStackInfo.LoopTime;
  1514.                 SaveCS := CurrentSlice;
  1515.                 PicBaseH[1] := PicBaseHandle;
  1516.                 revertable := false;
  1517.                 for i := 2 to nSlices do begin
  1518.                         h := NewHandle(PixMapSize);
  1519.                         if h = nil then begin
  1520.                                 nSlices := i - 1;
  1521.                                 leave;
  1522.                             end;
  1523.                         PicBaseH[i] := h;
  1524.                         CurrentSlice := i;
  1525.                         SelectSlice(i);
  1526.                         UpdateTitleBar;
  1527.                         DataSize := ImageSize;
  1528.                         err := SetFPos(f, fsFromStart, table[i - 1].offset);
  1529.                         err := fsread(f, DataSize, h^);
  1530.                         if odd(PixelsPerLine) then
  1531.                             UnpackLines;
  1532.                         if PictureType = InvertedTIFF then
  1533.                             InvertPic;
  1534.                         UpdatePicWindow;
  1535.                         if CommandPeriod then begin
  1536.                                 beep;
  1537.                                 nSlices := i;
  1538.                                 wait(60);
  1539.                                 leave;
  1540.                             end;
  1541.                     end; {for}
  1542.                 if (MaxBlock < MinFree) and (nSlices > 1) then begin
  1543.                         repeat
  1544.                             DisposHandle(PicBaseH[nSlices]);
  1545.                             nSlices := nSlices - 1;
  1546.                         until (MaxBlock > MinFree) or (nSlices = 1);
  1547.                         PutMessage(concat('Not enough memory to open all ', long2str(nExtraImages + 1), ' slices in the stack.'));
  1548.                     end;
  1549.                 CurrentSlice := SaveCS;
  1550.                 if CurrentSlice > nSlices then
  1551.                     CurrentSlice := 1;
  1552.                 SelectSlice(CurrentSlice);
  1553.                 UpdateTitleBar;
  1554.                 UpdateWindowsMenuItem(ImageSize * nSlices, title, PicNum);
  1555.             end;
  1556.     end;
  1557.  
  1558.  
  1559.     procedure OpenStack (f: integer);
  1560.         var
  1561.             table: TiffIFDTable;
  1562.             i, nExtraImages: integer;
  1563.             where: LongInt;
  1564.     begin
  1565.         nExtraImages := TempStackInfo.nSlices - 1;
  1566.         with info^ do begin
  1567.                 where := ImageDataOffset;
  1568.                 for i := 1 to nExtraImages do
  1569.                     with table[i] do begin
  1570.                             iWidth := PixelsPerLine;
  1571.                             iHeight := nLines;
  1572.                             where := where + ImageSize;
  1573.                             Offset := where;
  1574.                             invert := false;
  1575.                         end;
  1576.                 ReadStackSlices(f, nExtraImages, table);
  1577.             end;
  1578.     end;
  1579.  
  1580.  
  1581.     procedure OpenExtraTiffImages (f: integer; NextTiffIFD: LongInt);
  1582.         var
  1583.             table: TiffIFDTable;
  1584.             TiffInfo: TiffInfoRec;
  1585.             i, nExtraImages: integer;
  1586.             AllSameSize: boolean;
  1587.     begin
  1588.         nExtraImages := 0;
  1589.         repeat
  1590.             if not OpenTiffDirectory(f, NextTiffIFD, TiffInfo) then
  1591.                 exit(OpenExtraTiffImages);
  1592.             nExtraImages := nExtraImages + 1;
  1593.             with TiffInfo, table[nExtraImages] do begin
  1594.                     iWidth := width;
  1595.                     iHeight := height;
  1596.                     Offset := OffsetToData;
  1597.                     invert := ZeroIsBlack;
  1598.                     NextTiffIFD := NextIFD;
  1599.                 end;
  1600.         until (NextTiffIFD = 0) or (nExtraImages = MaxSlices);
  1601.         AllSameSize := true;
  1602.         with info^ do begin
  1603.                 for i := 1 to nExtraImages do
  1604.                     AllSameSize := AllSameSize and (PixelsPerLine = table[i].iWidth) and (nLines = table[i].iHeight);
  1605.                 if AllSameSize and not odd(PixelsPerLine) then
  1606.                     ReadStackSlices(f, nExtraImages, table);
  1607.             end;
  1608.     end;
  1609.  
  1610.  
  1611.     function OpenFile (fname: str255; vnum: integer): boolean;
  1612.         var
  1613.             ticks, ByteCount, i, DataSize, NextTiffIFD: LongInt;
  1614.             err: OSErr;
  1615.             f: integer;
  1616.             line, pixel: integer;
  1617.             r2, r3: rect;
  1618.             p: ptr;
  1619.             value: byte;
  1620.             iptr: ptr;
  1621.             SaveInfo: InfoPtr;
  1622.             is16bits: boolean;
  1623.     begin
  1624.         OpenFile := false;
  1625.         ShowWatch;
  1626.         err := fsopen(fname, vNum, f);
  1627.         SaveInfo := Info;
  1628.         iptr := NewPtr(SizeOf(PicInfo));
  1629.         if iptr = nil then begin
  1630.                 PutMemoryAlert;
  1631.                 DisposPtr(iptr);
  1632.                 err := fsclose(f);
  1633.                 exit(OpenFile)
  1634.             end;
  1635.         Info := pointer(iptr);
  1636.         info^ := SaveInfo^;
  1637.         with Info^ do begin
  1638.                 ColorMapOffset := 0;
  1639.                 if not OpenHeader(f, fname, vnum, NextTiffIFD) then begin
  1640.                         DisposPtr(iptr);
  1641.                         err := fsclose(f);
  1642.                         Info := SaveInfo;
  1643.                         exit(OpenFile)
  1644.                     end;
  1645.                 is16bits := (WhatToOpen = OpenCustom) and (ImportCustomDepth <> EightBits);
  1646.                 PicBaseAddr := GetImageMemory(SaveInfo, PicBaseHandle, is16bits);
  1647.                 if PicBaseAddr = nil then begin
  1648.                         err := fsclose(f);
  1649.                         exit(OpenFile)
  1650.                     end;
  1651.                 MakeNewWindow(fname);
  1652.                 err := SetFPos(f, fsFromStart, ImageDataOffset);
  1653.                 if PictureType = FourBitTIFF then
  1654.                     Read4BitTIFF(f)
  1655.                 else begin
  1656.                         DataSize := LongInt(nlines) * PixelsPerLine;
  1657.                         if is16bits then
  1658.                             DataSize := DataSize * 2;
  1659.                         err := fsread(f, DataSize, PicBaseAddr);
  1660.                         if IOCheck(err) <> NoErr then begin
  1661.                                 err := fsclose(f);
  1662.                                 exit(OpenFile)
  1663.                             end;
  1664.                     end;
  1665.                 if is16bits then
  1666.                     Import16BitImage;
  1667.                 if odd(PixelsPerLine) and (PictureType <> FourBitTiff) then
  1668.                     UnpackLines;
  1669.                 if (PictureType = pdp11) or (PictureType = InvertedTIFF) or ((PictureType = Imported) and is16bits) or ((PictureType = Imported) and (WhatToImport = ImportMCID)) then
  1670.                     InvertPic;
  1671.                 if PictureType = FourBitTIFF then
  1672.                     PictureType := imported;
  1673.                 vref := vnum;
  1674.                 if PixMapSize > UndoBufSize then
  1675.                     PutWarning;
  1676.                 revertable := FileDepth = EightBits;
  1677.             end; {with}
  1678.         if TempStackInfo.nSlices > 0 then
  1679.             OpenStack(f)
  1680.         else if NextTiffIFD > 0 then
  1681.             OpenExtraTiffImages(f, NextTiffIFD);
  1682.         err := fsclose(f);
  1683.         OpenFile := true;
  1684.     end;
  1685.  
  1686.  
  1687.     procedure InitPictBuffer (howBig: LongInt);
  1688.     begin
  1689.         repeat
  1690.             PictBuffer := NewPtr(howBig);
  1691.             if PictBuffer = nil then
  1692.                 howBig := howBig div 2;
  1693.         until PictBuffer <> nil;
  1694.         DisposPtr(PictBuffer);
  1695.         PictBuffer := NewPtr(howBig div 2);
  1696.     end;
  1697.  
  1698.  
  1699.     procedure FillPictBuffer;
  1700.         var
  1701.             count: LongInt;
  1702.             err: OSErr;
  1703.     begin
  1704.         count := GetPtrSize(PictBuffer);
  1705.         if not fitsInPictBuffer then begin
  1706.                 err := FSRead(PictF, count, PictBuffer);
  1707.                 if err <> NoErr then
  1708.                     PictReadErr := true;
  1709.             end;
  1710.         bytesInPictBuffer := count;
  1711.         curPictBufPtr := PictBuffer;
  1712.     end;
  1713.  
  1714.  
  1715.     procedure GetPICTData (dataPtr: Ptr; byteCount: Integer);
  1716.     {Input picture spooler routine taken from Apple's PICTViewer example program.}
  1717.         var
  1718.             count: LongInt;
  1719.             anErr: OSErr;
  1720.     begin
  1721.         count := byteCount;
  1722.         repeat
  1723.             if bytesInPictBuffer >= count then begin
  1724.                     BlockMove(curPictBufPtr, dataPtr, count);
  1725.                     curPictBufPtr := Ptr(Ord4(curPictBufPtr) + count);
  1726.                     bytesInPictBuffer := bytesInPictBuffer - count;
  1727.                     count := 0;
  1728.                 end
  1729.             else begin        {Not enough in buffer}
  1730.                     if bytesInPictBuffer > 0 then begin
  1731.                             BlockMove(curPictBufPtr, dataPtr, bytesInPictBuffer);
  1732.                             dataPtr := Ptr(Ord4(dataPtr) + bytesInPictBuffer);
  1733.                             count := count - bytesInPictBuffer;
  1734.                         end;
  1735.                     FillPictBuffer;
  1736.                 end;
  1737.         until count = 0;
  1738.     end;
  1739.  
  1740.  
  1741.     procedure BitInfo (var srcBits: PixMap; var srcRect, dstRect: rect; mode: integer; maskRgn: rgnHandle);
  1742.         var
  1743.             i, size: integer;
  1744.     begin
  1745.         if BitInfoCount = 0 then
  1746.             if srcBits.rowBytes < 0 then
  1747.                 with srcBits.pmTable^^ do begin{Make sure it is a PixMap.}
  1748.                         size := ctSize;
  1749.                         if size > 255 then
  1750.                             size := 255;
  1751.                         if size > 0 then
  1752.                             BitInfoCount := BitInfoCount + 1;
  1753.                         for i := 0 to size do
  1754.                             info^.cTable[i].rgb := ctTable[i].rgb;
  1755.                         if size > 0 then
  1756.                             with info^ do begin
  1757.                                     LutMode := ColorLut;
  1758.                                     SetupPseudocolor;
  1759.                                 end;
  1760.                     end;
  1761.     end;
  1762.  
  1763.  
  1764.     procedure GetClutFromPict (thePict: PicHandle);
  1765.   {Refer to "Screen Dump FKEY for Color Picts", February 1988 MacTutor.}
  1766.         type
  1767.             myPicData = record
  1768.                     p: Picture;
  1769.                     ID: integer
  1770.                 end;
  1771.             myPicPtr = ^myPicData;
  1772.             myPicHdl = ^myPicPtr;
  1773.         var
  1774.             tempProcs: CQDProcs;
  1775.             SaveProcsPtr: QDProcsPtr;
  1776.             tPort: GrafPtr;
  1777.             err: osErr;
  1778.     begin
  1779.         with info^ do begin
  1780.                 GetPort(tPort);
  1781.                 SetPort(wptr);
  1782.                 SaveProcsPtr := pointer(wptr^.grafProcs);
  1783.                 SetStdCProcs(tempProcs);
  1784.                 tempProcs.bitsProc := @BitInfo;
  1785.                 tempProcs.getPicProc := @GetPICTData;
  1786.                 BitInfoCount := 0;
  1787.                 wptr^.grafProcs := @tempProcs;
  1788.                 err := SetFPos(PictF, fsFromStart, 512 + SizeOf(Picture));
  1789.                 FillPictBuffer;
  1790.                 if not PictReadErr then
  1791.                     DrawPicture(thePict, thePict^^.picFrame);
  1792.                 SetPort(tPort);
  1793.                 wptr^.grafProcs := pointer(SaveProcsPtr);
  1794.             end;
  1795.         LoadLUT(info^.cTable);
  1796.     end;
  1797.  
  1798.  
  1799.     function OpenPict;{(fname:str255; vnum:integer; Reverting:boolean):boolean}
  1800.         var
  1801.             err: OSErr;
  1802.             i: integer;
  1803.             value: byte;
  1804.             iptr: ptr;
  1805.             PictSize, HowBig, NextTiffIFD: LongInt;
  1806.             thePict: PicHandle;
  1807.             tPort: GrafPtr;
  1808.             tempProcs: CQDProcs;
  1809.             SaveProcsPtr: QDProcsPtr;
  1810.             SaveInfo: InfoPtr;
  1811.  
  1812.         procedure Abort;
  1813.         begin
  1814.             if not reverting then begin
  1815.                     DisposPtr(pointer(Info));
  1816.                     Info := SaveInfo;
  1817.                     LoadLUT(info^.cTable);
  1818.                 end;
  1819.             if thePict <> nil then
  1820.                 DisposHandle(handle(thePict));
  1821.             if PictF <> 0 then
  1822.                 err := fsclose(PictF);
  1823.             exit(OpenPict);
  1824.         end;
  1825.  
  1826.     begin
  1827.         PictF := 0;
  1828.         thePict := nil;
  1829.         OpenPict := false;
  1830.         PictReadErr := false;
  1831.         ShowWatch;
  1832.         SaveInfo := Info;
  1833.         err := fsopen(fname, vNum, PictF);
  1834.         if IOCheck(err) <> 0 then
  1835.             Abort;
  1836.         if not Reverting then begin
  1837.                 iptr := NewPtr(SizeOf(PicInfo));
  1838.                 if iptr = nil then begin
  1839.                         PutMemoryAlert;
  1840.                         DisposPtr(iptr);
  1841.                         err := fsclose(PictF);
  1842.                         exit(OpenPict)
  1843.                     end;
  1844.                 Info := pointer(iptr);
  1845.                 info^ := SaveInfo^;
  1846.             end;
  1847.         with Info^ do begin
  1848.                 err := GetEof(PictF, PictSize);
  1849.                 if IOCheck(err) <> 0 then
  1850.                     Abort;
  1851.                 PictSize := PictSize - 512;
  1852.                 if PictSize <= 0 then
  1853.                     Abort;
  1854.                 WhatToOpen := OpenPICT2;
  1855.                 if not OpenHeader(PictF, fname, vnum, NextTiffIFD) then
  1856.                     Abort;
  1857.                 thePict := PicHandle(NewHandle(SizeOf(Picture)));
  1858.                 if thePict = nil then
  1859.                     Abort;
  1860.                 err := SetFPos(PictF, fsFromStart, 512);
  1861.                 if IOCheck(err) <> 0 then
  1862.                     Abort;
  1863.                 howBig := SizeOf(Picture);
  1864.                 err := FSRead(PictF, howBig, Pointer(thePict^));
  1865.                 if IOCheck(err) <> 0 then
  1866.                     Abort;
  1867.                 with thePict^^.PicFrame do begin
  1868.                         nlines := bottom - top;
  1869.                         PixelsPerLine := right - left;
  1870.                     end;
  1871.                 if not Reverting then begin
  1872.                         PicBaseAddr := GetImageMemory(SaveInfo, PicBaseHandle, false);
  1873.                         if PicBaseAddr = nil then begin
  1874.                                 DisposHandle(handle(thePict));
  1875.                                 err := fsclose(PictF);
  1876.                                 exit(OpenPict)
  1877.                             end;
  1878.                         MakeNewWindow(fname);
  1879.                     end;
  1880.                 if (PixMapSize > UndoBufSize) and (not Reverting) then begin
  1881.                         PutWarning;
  1882.                         ShowWatch;
  1883.                     end;
  1884.                 err := GetEof(PictF, howBig);
  1885.                 howBig := howBig - (512 + SizeOf(Picture));
  1886.                 InitPictBuffer(HowBig * 2);
  1887.                 if GetPtrSize(PictBuffer) >= howBig then begin
  1888.                         err := FSRead(PictF, howBig, PictBuffer);
  1889.                         if IOCheck(err) <> NoErr then begin
  1890.                                 DisposHandle(handle(thePict));
  1891.                                 err := fsclose(PictF);
  1892.                                 exit(OpenPict)
  1893.                             end;
  1894.                         fitsInPictBuffer := true;
  1895.                     end
  1896.                 else
  1897.                     fitsInPictBuffer := false;
  1898.                 if ((LutMode = ColorLut) or (LutMode = CustomGrayscale)) and (not UseExistingLUT) then
  1899.                     GetClutFromPict(thePict);
  1900.                 if isGrayScaleLUT then
  1901.                     ResetGrayMap;
  1902.                 GetPort(tPort);
  1903.                 SetPort(GrafPtr(osPort));
  1904.                 pmForeColor(BlackIndex);
  1905.                 pmBackColor(WhiteIndex);
  1906.                 RGBForeColor(BlackRGB);
  1907.                 RGBBackColor(WhiteRGB);
  1908.                 EraseRect(PicRect);
  1909.                 SaveProcsPtr := pointer(osPort^.grafProcs);
  1910.                 SetStdCProcs(tempProcs);
  1911.                 tempProcs.getPicProc := @GetPICTData;
  1912.                 osPort^.grafProcs := @TempProcs;
  1913.                 err := SetFPos(PictF, fsFromStart, 512 + SizeOf(Picture));
  1914.                 FillPictBuffer;
  1915.                 if not PictReadErr then
  1916.                     DrawPicture(thePict, PicRect);
  1917.                 osPort^.grafProcs := pointer(SaveProcsPtr);
  1918.                 DisposHandle(handle(thePict));
  1919.                 DisposPtr(PictBuffer);
  1920.                 pmForeColor(ForegroundIndex);
  1921.                 pmBackColor(BackgroundIndex);
  1922.                 SetPort(tPort);
  1923.                 vref := vnum;
  1924.                 PictureType := PictFile;
  1925.                 revertable := true;
  1926.             end; {with}
  1927.         err := fsclose(PictF);
  1928.         SetupUndo;
  1929.         if not PictReadErr then
  1930.             OpenPict := true;
  1931.     end;
  1932.  
  1933.  
  1934.     procedure GetCLUT (thePict: PicHandle);
  1935.         type
  1936.             myPicData = record
  1937.                     p: Picture;
  1938.                     ID: integer
  1939.                 end;
  1940.             myPicPtr = ^myPicData;
  1941.             myPicHdl = ^myPicPtr;
  1942.         var
  1943.             tempProcs: CQDProcs;
  1944.             SaveProcsPtr: QDProcsPtr;
  1945.             err: osErr;
  1946.     begin
  1947.         with info^ do begin
  1948.                 SetPort(wptr);
  1949.                 SaveProcsPtr := pointer(wptr^.grafProcs);
  1950.                 SetStdCProcs(tempProcs);
  1951.                 tempProcs.bitsProc := @BitInfo;
  1952.                 BitInfoCount := 0;
  1953.                 wptr^.grafProcs := @tempProcs;
  1954.                 DrawPicture(thePict, thePict^^.picFrame);
  1955.                 wptr^.grafProcs := pointer(SaveProcsPtr);
  1956.             end;
  1957.         LoadLUT(info^.cTable);
  1958.     end;
  1959.  
  1960.  
  1961.     function OpenPICS (name: str255; fRefNum: integer): boolean;
  1962.         var
  1963.             RefNum, picID, hOffset, vOffset: integer;
  1964.             err: OSErr;
  1965.             PicH: PicHandle;
  1966.             h: handle;
  1967.             MemError, Aborted: boolean;
  1968.             FrameRect: rect;
  1969.  
  1970.         procedure Abort;
  1971.         begin
  1972.             CloseResFile(RefNum);
  1973.             exit(OpenPICS);
  1974.         end;
  1975.  
  1976.     begin
  1977.         OpenPics := false;
  1978.         if MaxBlock < MinFree then begin
  1979.                 PutMessage('Insufficient memory to open PICS file.');
  1980.                 exit(OpenPICS);
  1981.             end;
  1982.         err := SetVol(nil, fRefNum);
  1983.         RefNum := OpenResFile(name);
  1984.         if RefNum = -1 then begin
  1985.                 PutMessage('Unable to open PICS file.');
  1986.                 exit(OpenPICS);
  1987.             end;
  1988.         PicH := GetPicture(128);
  1989.         if PicH = nil then
  1990.             Abort;
  1991.         FrameRect := PicH^^.PicFrame;
  1992.         with FrameRect do begin
  1993.                 hOffset := left;
  1994.                 vOffset := top;
  1995.                 right := right - hOffset;
  1996.                 bottom := bottom - vOffset;
  1997.                 left := 0;
  1998.                 top := 0;
  1999.             end;
  2000.         with FrameRect do
  2001.             if not NewPicWindow(name, right - left, bottom - top) then
  2002.                 Abort;
  2003.         with info^ do begin
  2004.                 revertable := false;
  2005.                 StackInfo := StackInfoPtr(NewPtr(SizeOf(StackInfoRec)));
  2006.                 if StackInfo = nil then
  2007.                     Abort;
  2008.                 with StackInfo^ do begin
  2009.                         SliceSpacing := 0.0;
  2010.                         LoopTime := 0.0;
  2011.                         nSlices := 1;
  2012.                         CurrentSlice := 1;
  2013.                         PicBaseH[1] := PicBaseHandle;
  2014.                     end;
  2015.             end;
  2016.         if not UseExistingLUT then
  2017.             GetCLUT(picH);
  2018.         with info^, Info^.StackInfo^ do begin
  2019.                 SetPort(GrafPtr(osPort));
  2020.                 DrawPicture(picH, PicRect);
  2021.                 DisposHandle(handle(picH));
  2022.                 UpdatePicWindow;
  2023.                 picID := 129;
  2024.                 MemError := false;
  2025.                 repeat
  2026.                     PicH := GetPicture(picID);
  2027.                     if (PicH = nil) or (ResError <> NoErr) then
  2028.                         Leave;
  2029.                     h := NewHandle(PixMapSize);
  2030.                     if (h = nil) or (MaxBlock < MinFree) then begin
  2031.                             if h <> nil then
  2032.                                 DisposHandle(h);
  2033.                             if PicH <> nil then
  2034.                                 DisposHandle(handle(picH));
  2035.                             MemError := true;
  2036.                             Leave;
  2037.                         end;
  2038.                     nSlices := nSlices + 1;
  2039.                     CurrentSlice := CurrentSlice + 1;
  2040.                     PicBaseH[CurrentSlice] := h;
  2041.                     SelectSlice(CurrentSlice);
  2042.                     FrameRect := PicH^^.PicFrame;
  2043.                     with FrameRect do begin
  2044.                             right := right - hOffset;
  2045.                             bottom := bottom - vOffset;
  2046.                             left := left - hOffset;
  2047.                             top := top - vOffset;
  2048.                         end;
  2049.                     if not EqualRect(FrameRect, PicRect) then
  2050.                         BlockMove(PicBaseH[CurrentSlice - 1]^, PicBaseH[CurrentSlice]^, PixMapSize);
  2051.                     DrawPicture(picH, FrameRect);
  2052.                     DisposHandle(handle(picH));
  2053.                     UpdatePicWindow;
  2054.                     UpdateTitleBar;
  2055.                     Aborted := CommandPeriod;
  2056.                     if Aborted then begin
  2057.                             beep;
  2058.                             wait(60);
  2059.                             Leave;
  2060.                         end;
  2061.                     picID := picID + 1;
  2062.                 until h = nil;
  2063.                 CloseResFile(RefNum);
  2064.                 if MemError then
  2065.                     PutMessage('Not enough memory to open all images in PICS file.');
  2066.                 CurrentSlice := 1;
  2067.                 SelectSlice(CurrentSlice);
  2068.                 PictureType := PicsFile;
  2069.                 Revertable := false;
  2070.                 UpdateTitleBar;
  2071.                 UpdateWindowsMenuItem(ImageSize * nSlices, title, PicNum);
  2072.                 if not MemError and not Aborted then
  2073.                     OpenPICS := true;
  2074.             end; {with}
  2075.     end;
  2076.  
  2077.  
  2078.     procedure OpenAll (reply: SFReply);
  2079.       {Opens all appropriate files in a folder.    Original version contributed by Ira Rampil.}
  2080.         var
  2081.             OpenedOK: boolean;
  2082.             RefNum, index: integer;
  2083.             name: Str255;
  2084.             ftype: OSType;
  2085.             err: OSErr;
  2086.             PB: HParamBlockRec;
  2087.     begin
  2088.         RefNum := reply.vRefNum;
  2089.         index := 0;
  2090.         while true do begin
  2091.                 index := index + 1;
  2092.                 with PB do begin
  2093.                         ioCompletion := nil;
  2094.                         ioNamePtr := @name;
  2095.                         ioVRefNum := RefNum;
  2096.                         ioVersNum := 0;
  2097.                         ioFDirIndex := index;
  2098.                         err := PBGetFInfo(@PB, false);
  2099.                         if err = fnfErr then
  2100.                             exit(OpenAll);
  2101.                         ftype := ioFlFndrInfo.fdType;
  2102.                     end;
  2103.                 if ftype = 'IPIC' then begin
  2104.                         WhatToOpen := OpenImage;
  2105.                         if not OpenFile(name, RefNum) then
  2106.                             exit(OpenAll);
  2107.                     end
  2108.                 else if ftype = 'PICT' then begin
  2109.                         if not OpenPICT(name, RefNum, false) then
  2110.                             exit(OpenAll)
  2111.                     end
  2112.                 else if ftype = 'TIFF' then begin
  2113.                         WhatToOpen := OpenTiff;
  2114.                         if not OpenFile(name, RefNum) then
  2115.                             exit(OpenAll);
  2116.                     end
  2117.                 else if ftype = 'PNTG' then
  2118.                     if not OpenMacPaint(name, RefNum) then
  2119.                         exit(OpenAll);
  2120.             end; {while}
  2121.     end;
  2122.  
  2123.  
  2124.     procedure UpdateFileIcons (reply: SFReply);
  2125.       {Changes the creator of all files in the current folder from 'IMAG'(files created by V1.40 and earlier) to 'Imag'.}
  2126.         var
  2127.             OpenedOK: boolean;
  2128.             RefNum, index: integer;
  2129.             name: Str255;
  2130.             ftype, fcreator: OSType;
  2131.             err: OSErr;
  2132.             PB: HParamBlockRec;
  2133.             TheInfo: FInfo;
  2134.             count: integer;
  2135.     begin
  2136.         RefNum := reply.vRefNum;
  2137.         index := 0;
  2138.         count := 0;
  2139.         ShowWatch;
  2140.         while true do begin
  2141.                 index := index + 1;
  2142.                 with PB do begin
  2143.                         ioCompletion := nil;
  2144.                         ioNamePtr := @name;
  2145.                         ioVRefNum := RefNum;
  2146.                         ioVersNum := 0;
  2147.                         ioFDirIndex := index;
  2148.                         err := PBGetFInfo(@PB, false);
  2149.                         if err = fnfErr then
  2150.                             leave;
  2151.                         ftype := ioFlFndrInfo.fdType;
  2152.                         fcreator := ioFlFndrInfo.fdCreator;
  2153.                     end;
  2154.                 if (fCreator = 'IMAG') and ((ftype = 'IPIC') or (ftype = 'PICT') or (ftype = 'TIFF') or (ftype = 'ICOL')) then begin
  2155.                         err := GetFInfo(name, RefNum, TheInfo);
  2156.                         if err <> NoErr then
  2157.                             leave;
  2158.                         TheInfo.fdCreator := 'Imag';
  2159.                         err := SetFInfo(name, RefNum, TheInfo);
  2160.                         if err <> NoErr then
  2161.                             leave;
  2162.                         err := FlushVol(nil, RefNum);
  2163.                         count := count + 1;
  2164.                     end;
  2165.             end; {while}
  2166.         if count = 0 then
  2167.             PutMessage('None of the files in the current folder use the old icons.')
  2168.         else
  2169.             PutMessage(concat('The creator type of ', long2str(count), ' files in the current folder was changed from ''IMAG'' to ''Imag''.'));
  2170.     end;
  2171.  
  2172.  
  2173.     function OpenDialogHook (item: integer; theDialog: DialogPtr): integer;
  2174.         const
  2175.             OpenAllID = 11;
  2176.             KeepLutID = 12;
  2177.             UpdateIconsID = 13;
  2178.         var
  2179.             i: integer;
  2180.     begin
  2181.         if (item = -1) and UseExistingLUT then
  2182.             SetDialogItem(theDialog, KeepLutID, 1);
  2183.         if item = OpenAllID then begin
  2184.                 OpenAllFiles := not OpenAllFiles;
  2185.                 SetDialogItem(theDialog, OpenAllID, ord(OpenAllFiles));
  2186.             end;
  2187.         if item = KeepLutID then begin
  2188.                 UseExistingLUT := not UseExistingLUT;
  2189.                 SetDialogItem(theDialog, KeepLutID, ord(UseExistingLut));
  2190.             end;
  2191.         if item = UpdateIconsID then begin
  2192.                 UpdateIcons := not UpdateIcons;
  2193.                 SetDialogItem(theDialog, UpdateIconsID, ord(UpdateIcons));
  2194.             end;
  2195.         OpenDialogHook := item;
  2196.     end;
  2197.  
  2198.  
  2199.     function DoOpen (FileName: str255; RefNum: integer): boolean;
  2200.         const
  2201.             MyDialogID = 70;
  2202.         var
  2203.             where: Point;
  2204.             reply: SFReply;
  2205.             b: boolean;
  2206.             sfPtr: ^SFTypeList;
  2207.             TypeList: array[0..8] of OSType;
  2208.             FileType: OSType;
  2209.             OKToContinue: boolean;
  2210.             FinderInfo: FInfo;
  2211.             err: OSErr;
  2212.     begin
  2213.         KillOperation;
  2214.         DisableDensitySlice;
  2215.         OpenAllFiles := false;
  2216.         UseExistingLUT := false;
  2217.         UpdateIcons := false;
  2218.         OKToContinue := false;
  2219.         if FileName = '' then begin
  2220.                 where.v := 50;
  2221.                 where.h := 50;
  2222.                 typeList[0] := 'IPIC';
  2223.                 typeList[1] := 'PICT';
  2224.                 typeList[2] := 'TIFF';
  2225.                 typeList[3] := 'ICOL';   {Color Tables}
  2226.                 typeList[4] := 'PX05'; {PixelPaint LUT}
  2227.                 typeList[5] := 'CLUT';  {Klutz LUT}
  2228.                 typeList[6] := 'drwC';  {Canvas LUT}
  2229.                 typeList[7] := 'PNTG';  {MacPaint}
  2230.                 typeList[8] := 'PICS';
  2231.                 typeList[9] := 'Iout';    {Outlines}
  2232.                 sfPtr := @TypeList;
  2233.                 SFPGetFile(Where, '', nil, 10, sfPtr^, @OpenDialogHook, reply, MyDialogID, nil);
  2234.                 if reply.good then
  2235.                     with reply do begin
  2236.                             FileName := fname;
  2237.                             FileType := ftype;
  2238.                             RefNum := vRefNum;
  2239.                             DefaultRefNum := RefNum;
  2240.                             DefaultFileName := fname;
  2241.                             OKToContinue := true;
  2242.                         end;
  2243.                 if reply.good and UpdateIcons then begin
  2244.                         UpdateFileIcons(reply);
  2245.                         exit(DoOpen);
  2246.                     end;
  2247.                 if reply.good and OpenAllFiles then begin
  2248.                         OpenAll(reply);
  2249.                         exit(DoOpen);
  2250.                     end;
  2251.             end
  2252.         else begin
  2253.                 err := GetFInfo(FileName, RefNum, FinderInfo);
  2254.                 FileType := FinderInfo.fdType;
  2255.                 OKToContinue := true;
  2256.             end;
  2257.         DoOpen := OKToContinue;
  2258.         if OKToContinue then begin
  2259.                 if FileType = 'IPIC' then begin
  2260.                         WhatToOpen := OpenImage;
  2261.                         b := OpenFile(FileName, RefNum)
  2262.                     end
  2263.                 else if FileType = 'PICT' then begin
  2264.                         b := OpenPICT(FileName, RefNum, false)
  2265.                     end
  2266.                 else if FileType = 'TIFF' then begin
  2267.                         WhatToOpen := OpenTIFF;
  2268.                         b := OpenFile(FileName, RefNum)
  2269.                     end
  2270.                 else if FileType = 'ICOL' then
  2271.                     OpenColorTable(FileName, RefNum)
  2272.                 else if FileType = 'PX05' then
  2273.                     ImportPalette('PX05', FileName, RefNum)
  2274.                 else if FileType = 'CLUT' then
  2275.                     ImportPalette('CLUT', FileName, RefNum)
  2276.                 else if FileType = 'drwC' then
  2277.                     ImportPalette('PX05', FileName, RefNum)
  2278.                 else if FileType = 'PNTG' then
  2279.                     b := OpenMacPaint(FileName, RefNum)
  2280.                 else if FileType = 'PICS' then
  2281.                     b := OpenPICS(FileName, RefNum)
  2282.                 else if FileType = 'Iout' then
  2283.                     OpenOutline(FileName, RefNum)
  2284.                 else begin
  2285.                         WhatToOpen := OpenUnknown;
  2286.                         b := OpenFile(FileName, RefNum)
  2287.                     end;
  2288.                 info^.ScaleToFitWindow := false;
  2289.             end;
  2290.     end;
  2291.  
  2292.  
  2293.     procedure ImportAllFiles (reply: SFReply);
  2294.         var
  2295.             OpenedOK: boolean;
  2296.             RefNum, index: integer;
  2297.             name: Str255;
  2298.             ftype: OSType;
  2299.             err: OSErr;
  2300.             PB: HParamBlockRec;
  2301.     begin
  2302.         RefNum := reply.vRefNum;
  2303.         index := 0;
  2304.         while true do begin
  2305.                 index := index + 1;
  2306.                 with PB do begin
  2307.                         ioCompletion := nil;
  2308.                         ioNamePtr := @name;
  2309.                         ioVRefNum := RefNum;
  2310.                         ioVersNum := 0;
  2311.                         ioFDirIndex := index;
  2312.                         err := PBGetFInfo(@PB, false);
  2313.                         if err = fnfErr then
  2314.                             exit(ImportAllFiles);
  2315.                         ftype := ioFlFndrInfo.fdType;
  2316.                     end;
  2317.                 if not OpenFile(name, RefNum) then
  2318.                     exit(ImportAllFiles);
  2319.                 if CommandPeriod then begin
  2320.                         beep;
  2321.                         exit(ImportAllFiles);
  2322.                     end;
  2323.             end; {while}
  2324.     end;
  2325.  
  2326.  
  2327.     procedure EditImportParameters;
  2328.         const
  2329.             WidthID = 2;
  2330.             HeightID = 3;
  2331.             OffsetID = 4;
  2332.             FixedID = 8;
  2333.             MinID = 11;
  2334.             MaxID = 12;
  2335.         var
  2336.             mylog: DialogPtr;
  2337.             item, fwidth: integer;
  2338.     begin
  2339.         mylog := GetNewDialog(110, nil, pointer(-1));
  2340.         SetDNum(MyLog, WidthID, ImportCustomWidth);
  2341.         SelIText(MyLog, WidthID, 0, 32767);
  2342.         SetDNum(MyLog, HeightID, ImportCustomHeight);
  2343.         SetDNum(MyLog, OffsetID, ImportCustomOffset);
  2344.         SetDialogItem(MyLog, FixedID, ord(not ImportAutoScale));
  2345.         if WhatToImport = ImportText then
  2346.             fwidth := 2
  2347.         else
  2348.             fwidth := 0;
  2349.         SetDReal(MyLog, MinID, ImportMin, fwidth);
  2350.         SetDReal(MyLog, MaxID, ImportMax, fwidth);
  2351.         OutlineButton(MyLog, ok, 16);
  2352.         repeat
  2353.             ModalDialog(nil, item);
  2354.             if item = WidthID then begin
  2355.                     ImportCustomWidth := GetDNum(MyLog, WidthID);
  2356.                     if (ImportCustomWidth < 0) or (ImportCustomWidth > MaxPicSize) then begin
  2357.                             ImportCustomWidth := 512;
  2358.                             SetDNum(MyLog, WidthID, ImportCustomWidth);
  2359.                         end;
  2360.                 end;
  2361.             if item = HeightID then begin
  2362.                     ImportCustomHeight := GetDNum(MyLog, HeightID);
  2363.                     if ImportCustomHeight < 0 then begin
  2364.                             ImportCustomHeight := 512;
  2365.                             SetDNum(MyLog, HeightID, ImportCustomHeight);
  2366.                         end;
  2367.                 end;
  2368.             if item = OffsetID then begin
  2369.                     ImportCustomOffset := GetDNum(MyLog, OffsetID);
  2370.                     if ImportCustomOffset < 0 then begin
  2371.                             ImportCustomOffset := 0;
  2372.                             SetDNum(MyLog, OffsetID, ImportCustomOffset);
  2373.                         end;
  2374.                 end;
  2375.             if item = FixedID then begin
  2376.                     ImportAutoScale := not ImportAutoScale;
  2377.                     SetDialogItem(mylog, FixedID, ord(not ImportAutoScale));
  2378.                 end;
  2379.             if item = MinID then begin
  2380.                     ImportMin := GetDReal(MyLog, MinID);
  2381.                     ImportAutoScale := false;
  2382.                     SetDialogItem(MyLog, FixedID, 1);
  2383.                 end;
  2384.             if item = MaxID then begin
  2385.                     ImportMax := GetDReal(MyLog, MaxID);
  2386.                     ImportAutoScale := false;
  2387.                     SetDialogItem(MyLog, FixedID, 1);
  2388.                 end;
  2389.         until item = ok;
  2390.         DisposDialog(mylog);
  2391.     end;
  2392.  
  2393.  
  2394.     function ImportDialogHook (item: integer; myLog: DialogPtr): integer;
  2395.         const
  2396.             TiffID = 11;
  2397.             McidID = 12;
  2398.             TextID = 13;
  2399.             LutID = 14;
  2400.             CustomID = 15;
  2401.             WidthAndHeightID = 16;
  2402.             OffsetID = 17;
  2403.             EightBitsID = 18;
  2404.             SixteenBitsUnsignedID = 19;
  2405.             SixteenBitsSignedID = 20;
  2406.             SwapBytesID = 21;
  2407.             ImportAllID = 22;
  2408.             EditID = 23;
  2409.             CalibrateID = 24;
  2410.         var
  2411.             i: integer;
  2412.  
  2413.         procedure SetRadioButtons1;
  2414.             var
  2415.                 i: integer;
  2416.         begin
  2417.             SetDialogItem(mylog, TiffID, 0);
  2418.             SetDialogItem(mylog, McidID, 0);
  2419.             SetDialogItem(mylog, LutID, 0);
  2420.             SetDialogItem(mylog, TextID, 0);
  2421.             SetDialogItem(mylog, CustomID, 0);
  2422.             case WhatToImport of
  2423.                 ImportTiff: 
  2424.                     SetDialogItem(mylog, TiffID, 1);
  2425.                 ImportMcid: 
  2426.                     SetDialogItem(mylog, McidID, 1);
  2427.                 ImportLUT: 
  2428.                     SetDialogItem(mylog, LutID, 1);
  2429.                 ImportText: 
  2430.                     SetDialogItem(mylog, TextID, 1);
  2431.                 ImportCustom: 
  2432.                     SetDialogItem(mylog, CustomID, 1);
  2433.             end;
  2434.         end;
  2435.  
  2436.         procedure SetRadioButtons2;
  2437.             var
  2438.                 i: integer;
  2439.         begin
  2440.             SetDialogItem(mylog, EightBitsID, 0);
  2441.             SetDialogItem(mylog, SixteenBitsUnsignedID, 0);
  2442.             SetDialogItem(mylog, SixteenBitsSignedID, 0);
  2443.             case ImportCustomDepth of
  2444.                 EightBits: 
  2445.                     SetDialogItem(mylog, EightBitsID, 1);
  2446.                 SixteenBitsUnsigned: 
  2447.                     SetDialogItem(mylog, SixteenBitsUnsignedID, 1);
  2448.                 SixteenBitsSigned: 
  2449.                     SetDialogItem(mylog, SixteenBitsSignedID, 1);
  2450.             end;
  2451.         end;
  2452.  
  2453.         procedure ShowParameters;
  2454.             var
  2455.                 str1, str2, str3: str255;
  2456.         begin
  2457.             NumToString(ImportCustomWidth, str1);
  2458.             NumToString(ImportCustomHeight, str2);
  2459.             NumToString(ImportCustomOffset, str3);
  2460.             ParamText(str1, str2, str3, '');
  2461.         end;
  2462.  
  2463.     begin
  2464.         if item = -1 then begin {Initialize}
  2465.                 SetRadioButtons1;
  2466.                 SetRadioButtons2;
  2467.                 ShowParameters;
  2468.                 SetDialogItem(mylog, SwapBytesID, ord(ImportSwapBytes));
  2469.                 SetDialogItem(mylog, ImportAllID, ord(ImportAll));
  2470.                 SetDialogItem(mylog, CalibrateID, ord(ImportCalibrate));
  2471.             end;
  2472.         if (item >= TiffID) and (item <= CustomID) then begin
  2473.                 case item of
  2474.                     TiffID: 
  2475.                         WhatToImport := ImportTiff;
  2476.                     McidID: 
  2477.                         WhatToImport := ImportMCID;
  2478.                     LutID: 
  2479.                         WhatToImport := ImportLUT;
  2480.                     TextID: 
  2481.                         WhatToImport := ImportText;
  2482.                     CustomID: 
  2483.                         WhatToImport := ImportCustom;
  2484.                 end;
  2485.                 SetRadioButtons1;
  2486.             end;
  2487.         if item = EditID then begin
  2488.                 EditImportParameters;
  2489.                 WhatToImport := ImportCustom;
  2490.                 SetRadioButtons1;
  2491.                 ShowParameters;
  2492.             end;
  2493.         if (item >= EightBitsID) and (item <= SixteenBitsSignedID) then begin
  2494.                 case item of
  2495.                     EightBitsID: 
  2496.                         ImportCustomDepth := EightBits;
  2497.                     SixteenBitsUnsignedID: 
  2498.                         ImportCustomDepth := SixteenBitsUnsigned;
  2499.                     SixteenBitsSignedID: 
  2500.                         ImportCustomDepth := SixteenBitsSigned;
  2501.                 end;
  2502.                 SetRadioButtons2;
  2503.                 WhatToImport := ImportCustom;
  2504.                 SetRadioButtons1;
  2505.             end;
  2506.         if item = SwapBytesID then begin
  2507.                 ImportSwapBytes := not ImportSwapBytes;
  2508.                 SetDialogItem(mylog, SwapBytesID, ord(ImportSwapBytes));
  2509.                 WhatToImport := ImportCustom;
  2510.                 SetRadioButtons1;
  2511.             end;
  2512.         if item = ImportAllID then begin
  2513.                 ImportAll := not ImportAll;
  2514.                 SetDialogItem(mylog, ImportAllID, ord(ImportAll));
  2515.             end;
  2516.         if item = CalibrateID then begin
  2517.                 ImportCalibrate := not ImportCalibrate;
  2518.                 SetDialogItem(mylog, CalibrateID, ord(ImportCalibrate));
  2519.                 WhatToImport := ImportCustom;
  2520.                 SetRadioButtons1;
  2521.             end;
  2522.         ImportDialogHook := item;
  2523.     end;
  2524.  
  2525.  
  2526.     function ImportFile (FileName: str255; RefNum: integer): boolean;
  2527.         const
  2528.             ImportDialogID = 90;
  2529.         var
  2530.             where: Point;
  2531.             typeList: SFTypeList;
  2532.             reply: SFReply;
  2533.             b: boolean;
  2534.     begin
  2535.         ImportFile := true;
  2536.         DisableDensitySlice;
  2537.         if not macro then
  2538.             ImportAll := false;
  2539.         if FileName = '' then begin
  2540.                 where.v := 50;
  2541.                 where.h := 50;
  2542.                 SFPGetFile(Where, '', nil, -1, typeList, @ImportDialogHook, reply, ImportDialogID, nil);
  2543.                 if not reply.good then begin
  2544.                         ImportFile := false;
  2545.                         exit(ImportFile);
  2546.                     end;
  2547.                 with reply do begin
  2548.                         FileName := fname;
  2549.                         RefNum := vRefNum;
  2550.                         DefaultRefNum := RefNum;
  2551.                         DefaultFileName := fname;
  2552.                     end;
  2553.             end;
  2554.         case WhatToImport of
  2555.             ImportTiff: 
  2556.                 WhatToOpen := OpenTiff;
  2557.             ImportMCID: 
  2558.                 WhatToOpen := OpenImported;
  2559.             ImportCustom:  begin
  2560.                     if (ImportCustomDepth <> EightBits) and (ImportCustomWidth > MaxLine) then begin
  2561.                             PutMessage(concat('Maximum width of imported 16-bit images is ', long2str(MaxLine), '.'));
  2562.                             exit(ImportFile);
  2563.                         end;
  2564.                     WhatToOpen := OpenCustom;
  2565.                 end;
  2566.             ImportLUT:  begin
  2567.                     DoImportLut(FileName, RefNum);
  2568.                     exit(ImportFile);
  2569.                 end;
  2570.             ImportText:  begin
  2571.                     ImportFile := ImportTextFile(FileName, RefNum);
  2572.                     exit(ImportFile);
  2573.                 end;
  2574.         end;
  2575.         if ImportAll then
  2576.             ImportAllFiles(reply)
  2577.         else
  2578.             b := OpenFile(FileName, RefNum);
  2579.     end;
  2580.  
  2581.  
  2582.     procedure RevertToSaved;
  2583.         var
  2584.             fname: str255;
  2585.             err, f: integer;
  2586.             ok: boolean;
  2587.     begin
  2588.         if OpPending then
  2589.             KillRoi;
  2590.         DisableDensitySlice;
  2591.         with Info^ do begin
  2592.                 fname := title;
  2593.                 SetPort(wptr);
  2594.                 if PictureType = PICTFile then begin
  2595.                         ok := OpenPICT(fname, vref, true);
  2596.                         UpdatePicWindow;
  2597.                     end
  2598.                 else begin
  2599.                         ShowWatch;
  2600.                         err := fsopen(fname, vref, f);
  2601.                         ok := true;
  2602.                         if HeaderOffset <> -1 then
  2603.                             ok := OpenImageHeader(f, fname, vref);
  2604.                         if ok then begin
  2605.                                 err := SetFPos(f, fsFromStart, ImageDataOffset);
  2606.                                 err := fsread(f, ImageSize, PicBaseAddr);
  2607.                                 with info^ do
  2608.                                     if (PictureType = PDP11) or (PictureType = InvertedTIFF) or (PictureType = imported) then
  2609.                                         InvertPic;
  2610.                                 if odd(PixelsPerLine) then
  2611.                                     UnpackLines;
  2612.                                 UpdatePicWindow;
  2613.                             end;
  2614.                         err := fsclose(f);
  2615.                         RoiShowing := false;
  2616.                     end;
  2617.                 OpPending := false;
  2618.                 Changes := false;
  2619.             end; {with}
  2620.     end;
  2621.  
  2622.  
  2623.     procedure FindWhatToPrint;
  2624.         var
  2625.             kind: integer;
  2626.             WhichWindow: WindowPtr;
  2627.     begin
  2628.         WhatToPrint := NothingToPrint;
  2629.         WhichWindow := FrontWindow;
  2630.         kind := WindowPeek(WhichWindow)^.WindowKind;
  2631.         if (kind = PicKind) and info^.RoiShowing and measuring then
  2632.             kind := ValuesKind;
  2633.         case kind of
  2634.             PicKind: 
  2635.                 if info^.RoiShowing then
  2636.                     WhatToPrint := PrintSelection
  2637.                 else
  2638.                     WhatToPRint := PrintImage;
  2639.             HistoKind: 
  2640.                 WhatToPrint := PrintHistogram;
  2641.             ProfilePlotKind, CalibrationPlotKind: 
  2642.                 WhatToPrint := PrintPlot;
  2643.             ValuesKind, ResultsKind: 
  2644.                 if mCount > 0 then
  2645.                     WhatToPrint := PrintMeasurements;
  2646.             otherwise
  2647.                 ;
  2648.         end;
  2649.         if (WhatToPrint = NothingToPRint) and (info <> NoInfo) then
  2650.             WhatToPrint := PrintImage;
  2651.     end;
  2652.  
  2653.  
  2654.     procedure UpdateFileMenu;
  2655.         var
  2656.             ShowItems, isSelection: boolean;
  2657.             i: integer;
  2658.             str, str2: str255;
  2659.             fwptr: WindowPtr;
  2660.             kind: integer;
  2661.     begin
  2662.         ShowItems := Info <> NoInfo;
  2663.         fwptr := FrontWindow;
  2664.         kind := WindowPeek(fwptr)^.WindowKind;
  2665.         with info^ do
  2666.             isSelection := RoiShowing and (RoiType = RectRoi);
  2667.         if OptionKeyWasDown then begin
  2668.                 SetItem(FileMenuH, CloseItem, 'Close All╔');
  2669.                 SetItem(FileMenuH, SaveItem, 'Save All');
  2670.                 SetMenuItem(FileMenuH, CloseItem, ShowItems);
  2671.             end
  2672.         else begin
  2673.                 SetItem(FileMenuH, CloseItem, 'Close╔');
  2674.                 with info^ do
  2675.                     if isSelection and (PictureType <> TiffFile) and (PictureType <> PictFile) and (kind = PicKind) then
  2676.                         SetItem(FileMenuH, SaveItem, 'Save Selection')
  2677.                     else
  2678.                         SetItem(FileMenuH, SaveItem, 'Save');
  2679.                 SetMenuItem(FileMenuH, CloseItem, ShowItems or (kind = ProfilePlotKind) or (kind = CalibrationPlotKind) or (kind = HistoKind));
  2680.             end;
  2681.         case kind of
  2682.             ProfilePlotKind, CalibrationPlotKind: 
  2683.                 ExportAsWhat := asPlotValues;
  2684.             HistoKind: 
  2685.                 ExportAsWhat := asHistogramValues;
  2686.             ResultsKind: 
  2687.                 ExportAsWhat := asMeasurements;
  2688.             PicKind:  begin
  2689.                     if (SaveAsWhat <> asPICT) then
  2690.                         SaveAsWhat := asTiff;
  2691.                     if (ExportAsWhat > asText) then
  2692.                         ExportAsWhat := asRaw;
  2693.                 end;
  2694.             otherwise
  2695.         end;
  2696.         if isSelection and (SaveAsWhat <> AsPalette) and (fwptr <> ResultsWindow) then
  2697.             SetItem(FileMenuH, SaveAsItem, 'Save Selection As╔')
  2698.         else
  2699.             SetItem(FileMenuH, SaveAsItem, 'Save As╔');
  2700.         if isSelection and (ExportAsWhat <= AsText) then
  2701.             SetItem(FileMenuH, ExportItem, 'Export Selection As╔')
  2702.         else
  2703.             SetItem(FileMenuH, ExportItem, 'Export╔');
  2704.         for i := SaveItem to SaveAsItem do
  2705.             SetMenuItem(FileMenuH, i, ShowItems);
  2706.         SetMenuItem(FileMenuH, ExportItem, ShowItems);
  2707.         if isSelection then
  2708.             str := 'Duplicate Selection'
  2709.         else
  2710.             str := 'Duplicate';
  2711.         SetItem(FileMenuH, DuplicateItem, str);
  2712.         for i := DuplicateItem to GetInfoItem do
  2713.             SetMenuItem(FileMenuH, i, ShowItems);
  2714.         SetMenuItem(FileMenuH, RevertItem, info^.Revertable);
  2715.         FindWhatToPrint;
  2716.         case WhatToPrint of
  2717.             NothingToPrint: 
  2718.                 str := '';
  2719.             PrintImage: 
  2720.                 str := 'Image';
  2721.             PrintSelection: 
  2722.                 str := 'Selection';
  2723.             PrintPlot: 
  2724.                 str := 'Plot';
  2725.             PrintHistogram: 
  2726.                 str := 'Histogram';
  2727.             PrintMeasurements: 
  2728.                 str := 'Measurements';
  2729.         end;
  2730.         SetItem(FileMenuH, PrintItem, concat('Print ', str, '╔'));
  2731.         SetMenuItem(FileMenuH, PrintItem, WhatToPrint <> NothingToPrint);
  2732.     end;
  2733.  
  2734.  
  2735.     procedure SaveAll;
  2736.         var
  2737.             SaveInfo: InfoPtr;
  2738.             i: integer;
  2739.     begin
  2740.         SaveInfo := Info;
  2741.         SaveAsWhat := AsTiff;
  2742.         SaveAllState := SaveAllStage1;
  2743.         for i := 1 to nPics do begin
  2744.                 Info := pointer(WindowPeek(PicWindow[i])^.RefCon);
  2745.                 SaveAs('', 0);
  2746.                 if CommandPeriod or (SaveAllState = NoSaveAll) then
  2747.                     leave;
  2748.             end;
  2749.         Info := SaveInfo;
  2750.         SaveAllState := NoSaveAll;
  2751.     end;
  2752.  
  2753.  
  2754.     procedure SaveScreen;
  2755.         var
  2756.             err, RefNum: integer;
  2757.             TheInfo: FInfo;
  2758.             name: str255;
  2759.             ok, NewFile: boolean;
  2760.             SaveInfo: InfoPtr;
  2761.             SaveNoInfoRec: PicInfo;
  2762.             ShutterSound: handle;
  2763.     begin
  2764.         name := 'Screen';
  2765.         err := GetVol(nil, RefNum);
  2766.         err := GetFInfo(name, RefNum, TheInfo);
  2767.         case err of
  2768.             NoErr:  begin
  2769.                     if TheInfo.fdType <> 'PICT' then begin
  2770.                             TypeMismatch(name);
  2771.                             exit(SaveScreen)
  2772.                         end;
  2773.                     NewFile := false;
  2774.                 end;
  2775.             FNFerr:  begin
  2776.                     err := create(name, RefNum, 'Imag', 'PICT');
  2777.                     if IOCheck(err) <> 0 then
  2778.                         exit(SaveScreen);
  2779.                     NewFile := true;
  2780.                 end;
  2781.             otherwise
  2782.                 if IOCheck(err) <> 0 then
  2783.                     exit(SaveScreen)
  2784.         end;
  2785.         ShutterSound := GetResource('snd ', 100);
  2786.         if ShutterSound <> nil then begin
  2787.                 err := SndPlay(nil, ShutterSound, false);
  2788.                 ReleaseResource(ShutterSound);
  2789.             end;
  2790.         SaveInfo := info;
  2791.         SaveNoInfoRec := NoInfoRec;
  2792.         with NoInfo^ do begin
  2793.                 PixelsPerLine := ScreenWidth;
  2794.                 nLines := ScreenHeight;
  2795.                 osPort := cScreenPort;
  2796.                 SetRect(PicRect, 0, 0, ScreenWidth, ScreenHeight);
  2797.                 LutMode := info^.LutMode;
  2798.                 cTable := info^.cTable;
  2799.             end;
  2800.         info := NoInfo;
  2801.         ok := SavePICTFile(name, RefNum, false, NewFile);
  2802.         NoInfoRec := SaveNoInfoRec;
  2803.         info := SaveInfo;
  2804.         if ok then
  2805.             PutMessage('The screen has been dumped to a PICT file named ╥Screen╙ in the same folder as Image.');
  2806.     end;
  2807.  
  2808.  
  2809.     function SuggestedExportName: str255;
  2810.         var
  2811.             name: str255;
  2812.     begin
  2813.         name := info^.title;
  2814.         case ExportAsWhat of
  2815.             asRaw, asMCID, asText:  begin
  2816.                     if name = 'Camera' then
  2817.                         name := 'Untitled';
  2818.                     if ExportAsWhat = AsText then
  2819.                         SuggestedExportName := concat(name, '(Text)')
  2820.                     else
  2821.                         SuggestedExportName := name;
  2822.                 end;
  2823.             AsLUT: 
  2824.                 SuggestedExportName := 'Palette';
  2825.             asMeasurements: 
  2826.                 SuggestedExportName := concat(name, '(Measurements)');
  2827.             AsPlotValues: 
  2828.                 SuggestedExportName := concat(name, '(Plot Values)');
  2829.             asHistogramValues: 
  2830.                 SuggestedExportName := concat(name, '(Histogram)');
  2831.             asCoordinates: 
  2832.                 SuggestedExportName := concat(name, '(Coordinates)');
  2833.         end;
  2834.     end;
  2835.  
  2836.  
  2837.     function ExportHook (item: integer; theDialog: DialogPtr): integer;
  2838.         const
  2839.             EditTextID = 7;
  2840.             RawID = 9;
  2841.             xyCoordinatesID = 16;
  2842.         var
  2843.             i: integer;
  2844.             fname: str255;
  2845.             NameEdited: boolean;
  2846.     begin
  2847.         if item = -1 then {Initialize}
  2848.             SetDialogItem(theDialog, RawID + ord(ExportAsWhat), 1);
  2849.         fname := GetDString(theDialog, EditTextID);
  2850.         NameEdited := fname <> SuggestedExportName;
  2851.         if (item >= RawID) and (item <= xyCoordinatesID) then begin
  2852.                 ExportAsWhat := ExportAsWhatType(item - RawID);
  2853.                 if not NameEdited then begin
  2854.                         SetDString(theDialog, EditTextID, SuggestedExportName);
  2855.                         SelIText(theDialog, EditTextID, 0, 32767);
  2856.                     end;
  2857.                 for i := RawID to xyCoordinatesID do
  2858.                     SetDialogItem(theDialog, i, 0);
  2859.                 SetDialogItem(theDialog, item, 1);
  2860.             end;
  2861.         ExportHook := item;
  2862.     end;
  2863.  
  2864.  
  2865.     procedure Export (name: str255; RefNum: integer);
  2866.         const
  2867.             CustomDialogID = 100;
  2868.         var
  2869.             where: Point;
  2870.             reply: SFReply;
  2871.             isSelection: boolean;
  2872.             kind: integer;
  2873.             SaveAsState: SaveAsWhatType;
  2874.     begin
  2875.         with info^ do begin
  2876.                 if (name = '') or (RefNum = 0) then begin
  2877.                         where.v := 50;
  2878.                         where.h := 50;
  2879.                         if name = '' then
  2880.                             name := SuggestedExportName;
  2881.                         SFPPutFile(Where, 'Save as?', name, @ExportHook, reply, CustomDialogID, nil);
  2882.                         if not reply.good then begin
  2883.                                 macro := false;
  2884.                                 exit(Export);
  2885.                             end;
  2886.                         with reply do begin
  2887.                                 name := fname;
  2888.                                 RefNum := vRefNum;
  2889.                                 DefaultRefNum := RefNum;
  2890.                             end;
  2891.                     end;
  2892.                 isSelection := RoiShowing and (RoiType = RectRoi);
  2893.                 case ExportAsWhat of
  2894.                     asRaw, asMCID:  begin
  2895.                             if ExportAsWhat = asMCID then
  2896.                                 InvertPic;
  2897.                             SaveAsState := SaveAsWhat;
  2898.                             if ExportAsWhat = AsRaw then
  2899.                                 SaveAsWhat := asRawData
  2900.                             else
  2901.                                 SaveAsWhat := SaveAsMCID;
  2902.                             if isSelection then
  2903.                                 SaveSelection(name, RefNum, false)
  2904.                             else
  2905.                                 SaveAsTIFF(name, RefNum, 0, 0, false);
  2906.                             SaveAsWhat := SaveAsState;
  2907.                         end;
  2908.                     AsText: 
  2909.                         ExportAsText(name, RefNum);
  2910.                     AsLUT: 
  2911.                         SaveLUT(name, RefNum);
  2912.                     asMeasurements: 
  2913.                         if mCount > 0 then
  2914.                             ExportMeasurements(name, RefNum)
  2915.                         else
  2916.                             PutMessage('Sorry, but no measurements are available to export.');
  2917.                     AsPlotValues: 
  2918.                         if PlotWindow <> nil then begin
  2919.                                 kind := WindowPeek(PlotWindow)^.WindowKind;
  2920.                                 case kind of
  2921.                                     ProfilePlotKind: 
  2922.                                         ConvertPlotToText;
  2923.                                     CalibrationPlotKind: 
  2924.                                         ConvertCalibrationCurveToText;
  2925.                                     otherwise
  2926.                                         TextBufSize := 0;
  2927.                                 end;
  2928.                                 SaveAsText(name, RefNum);
  2929.                             end
  2930.                         else
  2931.                             beep;
  2932.                     asHistogramValues: 
  2933.                         if HistoWindow <> nil then begin
  2934.                                 ConvertHistoToText;
  2935.                                 SaveAsText(name, RefNum);
  2936.                             end
  2937.                         else
  2938.                             beep;
  2939.                     asCoordinates: 
  2940.                         ExportCoordinates(name, RefNum);
  2941.                     otherwise
  2942.                         beep;
  2943.                 end; {case}
  2944.                 if (SaveAsWhat = asRawData) and (SaveAllState <> SaveAllStage2) then
  2945.                     SaveAsWhat := asTIFF;
  2946.             end; {with}
  2947.     end;
  2948.  
  2949.  
  2950.  
  2951. end.