1141cc406Sopenharmony_ci/* sane - Scanner Access Now Easy.
2141cc406Sopenharmony_ci   Copyright (C) 1997 Jeffrey S. Freedman
3141cc406Sopenharmony_ci   This file is part of the SANE package.
4141cc406Sopenharmony_ci
5141cc406Sopenharmony_ci   This program is free software; you can redistribute it and/or
6141cc406Sopenharmony_ci   modify it under the terms of the GNU General Public License as
7141cc406Sopenharmony_ci   published by the Free Software Foundation; either version 2 of the
8141cc406Sopenharmony_ci   License, or (at your option) any later version.
9141cc406Sopenharmony_ci
10141cc406Sopenharmony_ci   This program is distributed in the hope that it will be useful, but
11141cc406Sopenharmony_ci   WITHOUT ANY WARRANTY; without even the implied warranty of
12141cc406Sopenharmony_ci   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13141cc406Sopenharmony_ci   General Public License for more details.
14141cc406Sopenharmony_ci
15141cc406Sopenharmony_ci   You should have received a copy of the GNU General Public License
16141cc406Sopenharmony_ci   along with this program.  If not, see <https://www.gnu.org/licenses/>.
17141cc406Sopenharmony_ci
18141cc406Sopenharmony_ci   As a special exception, the authors of SANE give permission for
19141cc406Sopenharmony_ci   additional uses of the libraries contained in this release of SANE.
20141cc406Sopenharmony_ci
21141cc406Sopenharmony_ci   The exception is that, if you link a SANE library with other files
22141cc406Sopenharmony_ci   to produce an executable, this does not by itself cause the
23141cc406Sopenharmony_ci   resulting executable to be covered by the GNU General Public
24141cc406Sopenharmony_ci   License.  Your use of that executable is in no way restricted on
25141cc406Sopenharmony_ci   account of linking the SANE library code into it.
26141cc406Sopenharmony_ci
27141cc406Sopenharmony_ci   This exception does not, however, invalidate any other reasons why
28141cc406Sopenharmony_ci   the executable file might be covered by the GNU General Public
29141cc406Sopenharmony_ci   License.
30141cc406Sopenharmony_ci
31141cc406Sopenharmony_ci   If you submit changes to SANE to the maintainers to be included in
32141cc406Sopenharmony_ci   a subsequent release, you agree by submitting the changes that
33141cc406Sopenharmony_ci   those changes may be distributed with this exception intact.
34141cc406Sopenharmony_ci
35141cc406Sopenharmony_ci   If you write modifications of your own for SANE, it is your choice
36141cc406Sopenharmony_ci   whether to permit this exception to apply to your modifications.
37141cc406Sopenharmony_ci   If you do not wish that, delete this exception notice.  */
38141cc406Sopenharmony_ci
39141cc406Sopenharmony_ci/**
40141cc406Sopenharmony_ci **	ScanIt.java - Do the actual scanning for SANE.
41141cc406Sopenharmony_ci **
42141cc406Sopenharmony_ci **	Written: 11/3/97 - JSF
43141cc406Sopenharmony_ci **/
44141cc406Sopenharmony_ci
45141cc406Sopenharmony_ciimport java.util.Vector;
46141cc406Sopenharmony_ciimport java.util.Enumeration;
47141cc406Sopenharmony_ciimport java.awt.image.ImageProducer;
48141cc406Sopenharmony_ciimport java.awt.image.ImageConsumer;
49141cc406Sopenharmony_ciimport java.awt.image.ColorModel;
50141cc406Sopenharmony_ciimport java.io.OutputStream;
51141cc406Sopenharmony_ciimport java.io.PrintWriter;
52141cc406Sopenharmony_ciimport java.io.BufferedWriter;
53141cc406Sopenharmony_ciimport java.io.IOException;
54141cc406Sopenharmony_ci
55141cc406Sopenharmony_ci/*
56141cc406Sopenharmony_ci *	This class uses SANE to scan an image.
57141cc406Sopenharmony_ci */
58141cc406Sopenharmony_cipublic class ScanIt implements ImageProducer
59141cc406Sopenharmony_ci    {
60141cc406Sopenharmony_ci					// # lines we incr. image height.
61141cc406Sopenharmony_ci    private static final int STRIP_HEIGHT = 256;
62141cc406Sopenharmony_ci    private Sane sane;
63141cc406Sopenharmony_ci    private int handle = 0;		// SANE device handle.
64141cc406Sopenharmony_ci    private Vector consumers = new Vector();
65141cc406Sopenharmony_ci					// File to write to.
66141cc406Sopenharmony_ci    private OutputStream outputFile = null;
67141cc406Sopenharmony_ci    private SaneParameters parms = new SaneParameters();
68141cc406Sopenharmony_ci    private ColorModel cm;		// RGB color model.
69141cc406Sopenharmony_ci    private int width, height;		// Dimensions.
70141cc406Sopenharmony_ci    private int x, y;			// Position.
71141cc406Sopenharmony_ci    private int image[] = null;		// Image that we build as we scan.
72141cc406Sopenharmony_ci    private int offset;			// Offset within image in pixels if
73141cc406Sopenharmony_ci					//   doing separate frames, bytes
74141cc406Sopenharmony_ci					//   (3/word) if RBG.
75141cc406Sopenharmony_ci
76141cc406Sopenharmony_ci	/*
77141cc406Sopenharmony_ci	 *	Tell consumers our status.  The scan is also terminated de-
78141cc406Sopenharmony_ci	 *	pending on the status.
79141cc406Sopenharmony_ci	 */
80141cc406Sopenharmony_ci    private void tellStatus(int s)
81141cc406Sopenharmony_ci	{
82141cc406Sopenharmony_ci	Enumeration next = consumers.elements();
83141cc406Sopenharmony_ci	while (next.hasMoreElements())
84141cc406Sopenharmony_ci		{
85141cc406Sopenharmony_ci		ImageConsumer ic = (ImageConsumer) next.nextElement();
86141cc406Sopenharmony_ci		ic.imageComplete(s);
87141cc406Sopenharmony_ci		}
88141cc406Sopenharmony_ci					// Done?  Stop scan.
89141cc406Sopenharmony_ci	if (s == ImageConsumer.STATICIMAGEDONE ||
90141cc406Sopenharmony_ci	    s == ImageConsumer.IMAGEERROR)
91141cc406Sopenharmony_ci		sane.cancel(handle);
92141cc406Sopenharmony_ci	}
93141cc406Sopenharmony_ci
94141cc406Sopenharmony_ci	/*
95141cc406Sopenharmony_ci	 *	Tell consumers the image size.
96141cc406Sopenharmony_ci	 */
97141cc406Sopenharmony_ci    private void tellDimensions(int w, int h)
98141cc406Sopenharmony_ci	{
99141cc406Sopenharmony_ci	System.out.println("tellDimensions:  " + w + ", " + h);
100141cc406Sopenharmony_ci	Enumeration next = consumers.elements();
101141cc406Sopenharmony_ci	while (next.hasMoreElements())
102141cc406Sopenharmony_ci		{
103141cc406Sopenharmony_ci		ImageConsumer ic = (ImageConsumer) next.nextElement();
104141cc406Sopenharmony_ci		ic.setDimensions(w, h);
105141cc406Sopenharmony_ci		}
106141cc406Sopenharmony_ci	}
107141cc406Sopenharmony_ci
108141cc406Sopenharmony_ci	/*
109141cc406Sopenharmony_ci	 *	Send pixels to the clients.
110141cc406Sopenharmony_ci	 */
111141cc406Sopenharmony_ci    private void tellPixels(int x, int y, int w, int h)
112141cc406Sopenharmony_ci	{
113141cc406Sopenharmony_ci/*
114141cc406Sopenharmony_ci	System.out.println("image length=" + image.length);
115141cc406Sopenharmony_ci	System.out.println("width=" + width);
116141cc406Sopenharmony_ci	System.out.println("tellPixels:  x="+x +" y="+y + " w="+w
117141cc406Sopenharmony_ci					+ " h="+h);
118141cc406Sopenharmony_ci */
119141cc406Sopenharmony_ci	Enumeration next = consumers.elements();
120141cc406Sopenharmony_ci	while (next.hasMoreElements())
121141cc406Sopenharmony_ci		{
122141cc406Sopenharmony_ci		ImageConsumer ic = (ImageConsumer) next.nextElement();
123141cc406Sopenharmony_ci		ic.setPixels(x, y, w, h, cm, image, 0, width);
124141cc406Sopenharmony_ci		}
125141cc406Sopenharmony_ci	}
126141cc406Sopenharmony_ci
127141cc406Sopenharmony_ci	/*
128141cc406Sopenharmony_ci	 *	Construct.
129141cc406Sopenharmony_ci	 */
130141cc406Sopenharmony_ci    public ScanIt(Sane s, int hndl)
131141cc406Sopenharmony_ci	{
132141cc406Sopenharmony_ci	sane = s;
133141cc406Sopenharmony_ci	handle = hndl;
134141cc406Sopenharmony_ci	}
135141cc406Sopenharmony_ci
136141cc406Sopenharmony_ci	/*
137141cc406Sopenharmony_ci	 *	Add a consumer.
138141cc406Sopenharmony_ci	 */
139141cc406Sopenharmony_ci    public synchronized void addConsumer(ImageConsumer ic)
140141cc406Sopenharmony_ci	{
141141cc406Sopenharmony_ci	if (consumers.contains(ic))
142141cc406Sopenharmony_ci		return;			// Already here.
143141cc406Sopenharmony_ci	consumers.addElement(ic);
144141cc406Sopenharmony_ci	}
145141cc406Sopenharmony_ci
146141cc406Sopenharmony_ci	/*
147141cc406Sopenharmony_ci	 *	Is a consumer in the list?
148141cc406Sopenharmony_ci	 */
149141cc406Sopenharmony_ci    public synchronized boolean isConsumer(ImageConsumer ic)
150141cc406Sopenharmony_ci	{ return consumers.contains(ic); }
151141cc406Sopenharmony_ci
152141cc406Sopenharmony_ci	/*
153141cc406Sopenharmony_ci	 *	Remove consumer.
154141cc406Sopenharmony_ci	 */
155141cc406Sopenharmony_ci    public synchronized void removeConsumer(ImageConsumer ic)
156141cc406Sopenharmony_ci	{ consumers.removeElement(ic); }
157141cc406Sopenharmony_ci
158141cc406Sopenharmony_ci	/*
159141cc406Sopenharmony_ci	 *	Add a consumer and start scanning.
160141cc406Sopenharmony_ci	 */
161141cc406Sopenharmony_ci    public void startProduction(ImageConsumer ic)
162141cc406Sopenharmony_ci	{
163141cc406Sopenharmony_ci	System.out.println("In startProduction()");
164141cc406Sopenharmony_ci	addConsumer(ic);
165141cc406Sopenharmony_ci	scan();
166141cc406Sopenharmony_ci	}
167141cc406Sopenharmony_ci
168141cc406Sopenharmony_ci	/*
169141cc406Sopenharmony_ci	 *	Set file to write to.
170141cc406Sopenharmony_ci	 */
171141cc406Sopenharmony_ci    public void setOutputFile(OutputStream o)
172141cc406Sopenharmony_ci	{ outputFile = o; }
173141cc406Sopenharmony_ci
174141cc406Sopenharmony_ci	/*
175141cc406Sopenharmony_ci	 *	Ignore this:
176141cc406Sopenharmony_ci	 */
177141cc406Sopenharmony_ci    public void requestTopDownLeftRightResend(ImageConsumer ic)
178141cc406Sopenharmony_ci	{  }
179141cc406Sopenharmony_ci
180141cc406Sopenharmony_ci	/*
181141cc406Sopenharmony_ci	 *	Go to next line in image, reallocating if necessary.
182141cc406Sopenharmony_ci	 */
183141cc406Sopenharmony_ci    private void nextLine()
184141cc406Sopenharmony_ci	{
185141cc406Sopenharmony_ci	x = 0;
186141cc406Sopenharmony_ci	++y;
187141cc406Sopenharmony_ci	if (y >= height || image == null)
188141cc406Sopenharmony_ci		{			// Got to reallocate.
189141cc406Sopenharmony_ci		int oldSize = image == null ? 0 : width*height;
190141cc406Sopenharmony_ci		height += STRIP_HEIGHT;	// Add more lines.
191141cc406Sopenharmony_ci		int newSize = width*height;
192141cc406Sopenharmony_ci		int[] newImage = new int[newSize];
193141cc406Sopenharmony_ci		int i;
194141cc406Sopenharmony_ci		if (oldSize != 0)	// Copy old data.
195141cc406Sopenharmony_ci			for (i = 0; i < oldSize; i++)
196141cc406Sopenharmony_ci				newImage[i] = image[i];
197141cc406Sopenharmony_ci					// Fill new pixels with 0's, setting
198141cc406Sopenharmony_ci					//   alpha channel.
199141cc406Sopenharmony_ci		for (i = oldSize; i < newSize; i++)
200141cc406Sopenharmony_ci			newImage[i] = (255 << 24);
201141cc406Sopenharmony_ci		image = newImage;
202141cc406Sopenharmony_ci		System.out.println("nextLine:  newSize="+newSize);
203141cc406Sopenharmony_ci					// Tell clients.
204141cc406Sopenharmony_ci		tellDimensions(width, height);
205141cc406Sopenharmony_ci		}
206141cc406Sopenharmony_ci	}
207141cc406Sopenharmony_ci
208141cc406Sopenharmony_ci	/*
209141cc406Sopenharmony_ci	 *	Process a buffer of data.
210141cc406Sopenharmony_ci	 */
211141cc406Sopenharmony_ci    private boolean process(byte[] data, int readLen)
212141cc406Sopenharmony_ci	{
213141cc406Sopenharmony_ci	int prevY = y > 0 ? y : 0;	// Save current Y-coord.
214141cc406Sopenharmony_ci	int i;
215141cc406Sopenharmony_ci	switch (parms.format)
216141cc406Sopenharmony_ci		{
217141cc406Sopenharmony_ci	case SaneParameters.FRAME_RED:
218141cc406Sopenharmony_ci	case SaneParameters.FRAME_GREEN:
219141cc406Sopenharmony_ci	case SaneParameters.FRAME_BLUE:
220141cc406Sopenharmony_ci		System.out.println("Process RED, GREEN or BLUE");
221141cc406Sopenharmony_ci		int cindex = 2 - (parms.format - SaneParameters.FRAME_RED);
222141cc406Sopenharmony_ci					// Single frame.
223141cc406Sopenharmony_ci		for (i = 0; i < readLen; ++i)
224141cc406Sopenharmony_ci			{		// Doing a single color frame.
225141cc406Sopenharmony_ci			image[offset + i] |=
226141cc406Sopenharmony_ci				(((int) data[i]) & 0xff) << (8*cindex);
227141cc406Sopenharmony_ci			++x;
228141cc406Sopenharmony_ci			if (x >= width)
229141cc406Sopenharmony_ci				nextLine();
230141cc406Sopenharmony_ci			}
231141cc406Sopenharmony_ci		break;
232141cc406Sopenharmony_ci	case SaneParameters.FRAME_RGB:
233141cc406Sopenharmony_ci		for (i = 0; i < readLen; ++i)
234141cc406Sopenharmony_ci			{
235141cc406Sopenharmony_ci			int b = 2 - (offset + i)%3;
236141cc406Sopenharmony_ci			image[(offset + i)/3] |=
237141cc406Sopenharmony_ci				(((int) data[i]) & 0xff) << (8*b);
238141cc406Sopenharmony_ci			if (b == 0)
239141cc406Sopenharmony_ci				{
240141cc406Sopenharmony_ci				++x;
241141cc406Sopenharmony_ci				if (x >= width)
242141cc406Sopenharmony_ci					nextLine();
243141cc406Sopenharmony_ci				}
244141cc406Sopenharmony_ci			}
245141cc406Sopenharmony_ci		break;
246141cc406Sopenharmony_ci	case SaneParameters.FRAME_GRAY:
247141cc406Sopenharmony_ci		System.out.println("Process GREY");
248141cc406Sopenharmony_ci					// Single frame.
249141cc406Sopenharmony_ci		for (i = 0; i < readLen; ++i)
250141cc406Sopenharmony_ci			{
251141cc406Sopenharmony_ci			int v = ((int) data[i]) & 0xff;
252141cc406Sopenharmony_ci			image[offset + i] |= (v<<16) | (v<<8) | (v);
253141cc406Sopenharmony_ci			++x;
254141cc406Sopenharmony_ci			if (x >= width)
255141cc406Sopenharmony_ci				nextLine();
256141cc406Sopenharmony_ci			}
257141cc406Sopenharmony_ci		break;
258141cc406Sopenharmony_ci		}
259141cc406Sopenharmony_ci	offset += readLen;		// Update where we are.
260141cc406Sopenharmony_ci					// Show it.
261141cc406Sopenharmony_ci	System.out.println("PrevY = " + prevY + ", y = " + y);
262141cc406Sopenharmony_ci//	tellPixels(0, prevY, width, y - prevY);
263141cc406Sopenharmony_ci	tellPixels(0, 0, width, height);
264141cc406Sopenharmony_ci	return true;
265141cc406Sopenharmony_ci	}
266141cc406Sopenharmony_ci
267141cc406Sopenharmony_ci	/*
268141cc406Sopenharmony_ci	 *	Start scanning.
269141cc406Sopenharmony_ci	 */
270141cc406Sopenharmony_ci    public void scan()
271141cc406Sopenharmony_ci	{
272141cc406Sopenharmony_ci	int dataLen = 32*1024;
273141cc406Sopenharmony_ci	byte [] data = new byte[dataLen];
274141cc406Sopenharmony_ci	int [] readLen = new int[1];
275141cc406Sopenharmony_ci	int frameCnt = 0;
276141cc406Sopenharmony_ci					// For now, use default RGB model.
277141cc406Sopenharmony_ci	cm = ColorModel.getRGBdefault();
278141cc406Sopenharmony_ci	int status;
279141cc406Sopenharmony_ci	image = null;
280141cc406Sopenharmony_ci	do				// Do each frame.
281141cc406Sopenharmony_ci		{
282141cc406Sopenharmony_ci		frameCnt++;
283141cc406Sopenharmony_ci		x = 0;			// Init. position.
284141cc406Sopenharmony_ci		y = -1;
285141cc406Sopenharmony_ci		offset = 0;
286141cc406Sopenharmony_ci		System.out.println("Reading frame #" + frameCnt);
287141cc406Sopenharmony_ci		status = sane.start(handle);
288141cc406Sopenharmony_ci		if (status != Sane.STATUS_GOOD)
289141cc406Sopenharmony_ci			{
290141cc406Sopenharmony_ci			System.out.println("start() failed.  Status= "
291141cc406Sopenharmony_ci								+ status);
292141cc406Sopenharmony_ci			tellStatus(ImageConsumer.IMAGEERROR);
293141cc406Sopenharmony_ci			return;
294141cc406Sopenharmony_ci			}
295141cc406Sopenharmony_ci		status = sane.getParameters(handle, parms);
296141cc406Sopenharmony_ci		if (status != Sane.STATUS_GOOD)
297141cc406Sopenharmony_ci			{
298141cc406Sopenharmony_ci			System.out.println("getParameters() failed.  Status= "
299141cc406Sopenharmony_ci								+ status);
300141cc406Sopenharmony_ci			tellStatus(ImageConsumer.IMAGEERROR);
301141cc406Sopenharmony_ci			return;	//++++cleanup.
302141cc406Sopenharmony_ci			}
303141cc406Sopenharmony_ci		if (frameCnt == 1)	// First time?
304141cc406Sopenharmony_ci			{
305141cc406Sopenharmony_ci			width = parms.pixelsPerLine;
306141cc406Sopenharmony_ci			if (parms.lines >= 0)
307141cc406Sopenharmony_ci				height = parms.lines - STRIP_HEIGHT + 1;
308141cc406Sopenharmony_ci			else		// Hand-scanner.
309141cc406Sopenharmony_ci				height = 0;
310141cc406Sopenharmony_ci			nextLine();	// Allocate image.
311141cc406Sopenharmony_ci			}
312141cc406Sopenharmony_ci		while ((status = sane.read(handle, data, dataLen, readLen))
313141cc406Sopenharmony_ci							== Sane.STATUS_GOOD)
314141cc406Sopenharmony_ci			{
315141cc406Sopenharmony_ci			System.out.println("Read " + readLen[0] + " bytes.");
316141cc406Sopenharmony_ci			if (!process(data, readLen[0]))
317141cc406Sopenharmony_ci				{
318141cc406Sopenharmony_ci				tellStatus(ImageConsumer.IMAGEERROR);
319141cc406Sopenharmony_ci				return;
320141cc406Sopenharmony_ci				}
321141cc406Sopenharmony_ci			}
322141cc406Sopenharmony_ci		if (status != Sane.STATUS_EOF)
323141cc406Sopenharmony_ci			{
324141cc406Sopenharmony_ci			System.out.println("read() failed.  Status= "
325141cc406Sopenharmony_ci								+ status);
326141cc406Sopenharmony_ci			tellStatus(ImageConsumer.IMAGEERROR);
327141cc406Sopenharmony_ci			return;
328141cc406Sopenharmony_ci			}
329141cc406Sopenharmony_ci		}
330141cc406Sopenharmony_ci	while (!parms.lastFrame);
331141cc406Sopenharmony_ci	height = y;			// For now, send whole image here.
332141cc406Sopenharmony_ci	tellDimensions(width, height);
333141cc406Sopenharmony_ci	tellPixels(0, 0, width, height);
334141cc406Sopenharmony_ci	if (outputFile != null)		// Write to file.
335141cc406Sopenharmony_ci		{
336141cc406Sopenharmony_ci		try
337141cc406Sopenharmony_ci			{
338141cc406Sopenharmony_ci			write(outputFile);
339141cc406Sopenharmony_ci			}
340141cc406Sopenharmony_ci		catch (IOException e)
341141cc406Sopenharmony_ci			{	//+++++++++++++++
342141cc406Sopenharmony_ci			System.out.println("I/O error writing file.");
343141cc406Sopenharmony_ci			}
344141cc406Sopenharmony_ci		outputFile = null;	// Clear for next time.
345141cc406Sopenharmony_ci		}
346141cc406Sopenharmony_ci	tellStatus(ImageConsumer.STATICIMAGEDONE);
347141cc406Sopenharmony_ci	image = null;			// Allow buffer to be freed.
348141cc406Sopenharmony_ci	}
349141cc406Sopenharmony_ci
350141cc406Sopenharmony_ci	/*
351141cc406Sopenharmony_ci	 *	Write ppm/pnm output for last scan to a file.
352141cc406Sopenharmony_ci	 */
353141cc406Sopenharmony_ci    private void write(OutputStream out) throws IOException
354141cc406Sopenharmony_ci	{
355141cc406Sopenharmony_ci	PrintWriter pout = new PrintWriter(out);
356141cc406Sopenharmony_ci	BufferedWriter bout = new BufferedWriter(pout);
357141cc406Sopenharmony_ci	int len = width*height;		// Get # of pixels.
358141cc406Sopenharmony_ci	int i;
359141cc406Sopenharmony_ci	switch (parms.format)
360141cc406Sopenharmony_ci		{
361141cc406Sopenharmony_ci	case SaneParameters.FRAME_RED:
362141cc406Sopenharmony_ci	case SaneParameters.FRAME_GREEN:
363141cc406Sopenharmony_ci	case SaneParameters.FRAME_BLUE:
364141cc406Sopenharmony_ci	case SaneParameters.FRAME_RGB:
365141cc406Sopenharmony_ci		pout.print("P6\n# SANE data follows\n" +
366141cc406Sopenharmony_ci			width + ' ' + height + "\n255\n");
367141cc406Sopenharmony_ci		for (i = 0; i < len; i++)
368141cc406Sopenharmony_ci			{
369141cc406Sopenharmony_ci			int pix = image[i];
370141cc406Sopenharmony_ci			bout.write((pix >> 16) & 0xff);
371141cc406Sopenharmony_ci			bout.write((pix >> 8) & 0xff);
372141cc406Sopenharmony_ci			bout.write(pix & 0xff);
373141cc406Sopenharmony_ci			}
374141cc406Sopenharmony_ci		break;
375141cc406Sopenharmony_ci	case SaneParameters.FRAME_GRAY:
376141cc406Sopenharmony_ci		pout.print("P5\n# SANE data follows\n" +
377141cc406Sopenharmony_ci			width + ' ' + height + "\n255\n");
378141cc406Sopenharmony_ci		for (i = 0; i < len; i++)
379141cc406Sopenharmony_ci			{
380141cc406Sopenharmony_ci			int pix = image[i];
381141cc406Sopenharmony_ci			bout.write(pix & 0xff);
382141cc406Sopenharmony_ci			}
383141cc406Sopenharmony_ci		break;
384141cc406Sopenharmony_ci		}
385141cc406Sopenharmony_ci
386141cc406Sopenharmony_ci	bout.flush();			// Flush output.
387141cc406Sopenharmony_ci	pout.flush();
388141cc406Sopenharmony_ci	}
389141cc406Sopenharmony_ci    }
390