示例#1
0
static void fail (PIC_PARM *pp, long error_code)
{
	//terminates Pegasus and sets error code

	Pegasus (pp, REQ_TERM);
	pp->Status = error_code;
	if (inhandle != -1)
	{
		close (inhandle);
		inhandle = -1;
	}
	if (outhandle != -1)
	{
		close (outhandle);
		outhandle = -1;
	}
	remove (outfilename);
	printf ("!!!!Error -- code %ld\n", error_code);
	return;
}
示例#2
0
static long palettize_file (char *file1, char *file2, char *file3)
{
	long error = 1;
	long n_input_colors;
	int i;
	RESPONSE res;
	BITMAPFILEHEADER bf;
	BITMAPINFOHEADER bi;

	inhandle = -1;
	outhandle = -1;
	palhandle = -1;

	//open the 3 files
	inhandle = open (file1, O_RDONLY | O_BINARY);
	if (inhandle == -1)
	{
		printf ("***** unable to open input image %s\n", file1);
		goto ehandler;
	}
	outhandle = open (file2, O_RDWR | O_BINARY | O_CREAT | O_TRUNC,
		S_IREAD | S_IWRITE);
	if (outhandle == -1)
	{
		printf ("***** unable to create output file %s\n", file2);
		goto ehandler;
	}
	palhandle = open (file3, O_RDONLY | O_BINARY);
	if (palhandle == -1)
	{
		printf ("***** unable to open palette file %s\n", file3);
		goto ehandler;
	}

	//skip the bitmapfileheader of the palette file, and read the
	// bitmapinfoheader
	if (filelength (palhandle) < sizeof (BITMAPFILEHEADER)
		+ sizeof (BITMAPINFOHEADER))
	{
		printf ("***** invalid input palette file\n");
		goto ehandler;
	}
	lseek (palhandle, sizeof (BITMAPFILEHEADER), SEEK_SET);
	read (palhandle, &bi, sizeof (BITMAPINFOHEADER));
	if (bi.biBitCount != 1 && bi.biBitCount != 4 && bi.biBitCount != 8)
	{
		printf ("***** input palette file is not 1, 4, or 8 bits per pixel\n");
		goto ehandler;
	}
	palbuf.ncolors = (int)bi.biClrUsed;
	if (palbuf.ncolors == 0)
	{
		palbuf.ncolors = 1 << bi.biBitCount;
	}
	else
	{
		if (palbuf.ncolors > (1 << bi.biBitCount) || palbuf.ncolors < 2)
		{
			printf ("***** palette file error -- bad number of colors\n");
			goto ehandler;
		}
	}
	//read those colors
	read (palhandle, &palbuf.rgb[0], palbuf.ncolors << 2);
	for (i=0; i<palbuf.ncolors; i++)
	{
		//clear reserved bits for safety
		palbuf.rgb[i].rgbReserved = 0;
	}

	infilesize = filelength (inhandle);
	total_bytes_read = 0;

	//write a dummy bitmapfileheader for now
	write (outhandle, &bf, sizeof (BITMAPFILEHEADER));
	//write a dummy bitmapinfoheader for now
	write (outhandle, &bi, sizeof (BITMAPINFOHEADER));
	//write the new palette
	write (outhandle, &palbuf.rgb[0], palbuf.ncolors << 2);

	//now set up for opcode 82
	memset (&pp, 0, sizeof (pp));	//VERY IMPORTANT!
	pp.Op = OP_UTL;		//Utility opcode (82)
	pp.ParmSize = sizeof (pp);
	pp.ParmVer = CURRENT_PARMVER;	//from pic.h

	//get the input file's bitmapinfoheader into pp.Head
	// -- skip the BITMAPFILEHEADER
	lseek (inhandle, sizeof (BITMAPFILEHEADER), SEEK_SET);
	read (inhandle, &pp.Head, sizeof (BITMAPINFOHEADER));
	seek_adder = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER);
	//if the input file is < 24bpp, read in that palette
	if (pp.Head.biBitCount <= 8)
	{
		if (pp.Head.biClrUsed == 0)
		{
			//0 means max colors
			n_input_colors = (1 << pp.Head.biBitCount);
		}
		else
		{
			n_input_colors = pp.Head.biClrUsed;
		}
		if (n_input_colors < 2 || n_input_colors > (1 << pp.Head.biBitCount))
		{
			printf ("***** input palette has bad color count\n");
			goto ehandler;
		}
		read (inhandle, pp.ColorTable, (unsigned short)n_input_colors << 2);
		seek_adder += (n_input_colors << 2);
	}
	//NOTE: at this point, seek_adder is the offset in the input file of
	// the dib bits
	pp.u.UTL.Subcode = 8;	//"Palettize to given palette"

	pp.u.UTL.ptr1 = NULL;	//actually, already null
	pp.u.UTL.ptr2 = NULL;   //ditto
	pp.u.UTL.OutBpp = 8;	//output bit depth -- could also be 1 or 4
	if (do_dither)
	{
		pp.u.UTL.PicFlags = PF_Dither;
	}
	pp.u.UTL.ptr3 = ((BYTE PICHUGE *)&palbuf) + 2;	//the palette to reduce to
	pp.u.UTL.NumColors = palbuf.ncolors;	//number of colors to reduce to
    	pp.u.UTL.AllocType = 0;	//we will not allocate full buffers for the
		//input and output files -- we will just process in serial "chunks"

	pp.Get.Start = input_queue;
	pp.Get.Front = pp.Get.Rear = pp.Get.Start;
	pp.Get.End = pp.Get.Start + inbufsize + 1;

	pp.Put.Start = output_queue;
	pp.Put.Front = pp.Put.Rear = pp.Put.Start;
	pp.Put.End = pp.Put.Start + outbufsize + 1;

	getdata_already_called = 0;
	lseek (inhandle, seek_adder, SEEK_SET);
		//seek to the beginning of the dib bits

	//the Pegasus loops
	res = Pegasus (&pp, REQ_INIT);
	while (res != RES_DONE)
	{
		if (res == RES_GET_NEED_DATA || res == RES_GET_DATA_YIELD)
		{
			getdata (&pp);
		}
		else if (res == RES_PUT_DATA_YIELD || res == RES_PUT_NEED_SPACE)
		{
			putdata (&pp);
		}
		//NOTE: RES_SEEK is never requested for subcode 8
		else
		{
			if (res != RES_ERR)
			{
				pp.Status = ERR_UNKNOWN_RESPONSE;
			}
			fail (&pp, pp.Status);
			return FALSE;
		}
		//actually, for this subcode, INIT does basicallay nothing
		res = Pegasus (&pp, REQ_CONT);
	}

	res = Pegasus (&pp, REQ_EXEC);
	while (res != RES_DONE)
	{
		if (res == RES_GET_NEED_DATA || res == RES_GET_DATA_YIELD)
		{
			getdata (&pp);
		}
		else if (res == RES_PUT_DATA_YIELD || res == RES_PUT_NEED_SPACE)
		{
			putdata (&pp);
		}
		//NOTE RES_SEEK is never requested for subcode 8
		else
		{
			if (res != RES_ERR)
			{
				pp.Status = ERR_UNKNOWN_RESPONSE;
			}
			fail (&pp, pp.Status);
			return FALSE;
		}
		res = Pegasus (&pp, REQ_CONT);
	}

	//flush the output
	if (pp.Put.Front != pp.Put.Rear)
	{
		putdata (&pp);
	}

	//write the bitmapfileheader out
	lseek (outhandle, 0, SEEK_SET);
	bf.bfType = 'B' + ('M' << 8);
	bf.bfReserved1 = 0;
	bf.bfReserved2 = 0;
	bf.bfSize = filelength (outhandle);
	//where the bitmap image is:
	bf.bfOffBits = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER)
		+ (palbuf.ncolors << 2);
	write (outhandle, &bf, sizeof (BITMAPFILEHEADER));

	//write the bitmapinfoheader out
	//but first, set the number of colors -- color reduction might use
	// less than we request, and bi must match the palette we previously
	// output
	pp.u.UTL.BiOut.biClrUsed = pp.u.UTL.BiOut.biClrImportant
		= palbuf.ncolors;
	write (outhandle, &pp.u.UTL.BiOut, sizeof (BITMAPINFOHEADER));

	Pegasus (&pp, REQ_TERM);
	error = 0;

ehandler:
	if (inhandle != -1)
	{
		close (inhandle);
		inhandle = -1;
	}
	if (outhandle != -1)
	{
		close (outhandle);
		outhandle = -1;
	}
	if (palhandle != -1)
	{
		close (palhandle);
		palhandle = -1;
	}
	if (error)
	{
		remove (file2);
	}
	else
	{
		filecount++;
	}
	return error;
}
示例#3
0
/*  �����������������������������������������������������������������������ͼ */
PRIVATE LONG  expand (void)
{
	PIC_PARM  p;
	RESPONSE    res;
	LONG	len;
	LONG	ct;
	LONG	local_status;
	LONG	join_offset = 0;
	LONG	k, region_x,region_y,region_endx,region_endy, region_w,region_h;
	BYTE	*bptr;
	BYTE	*region_info_ptr;
	REGION_INFO	*region_info;

		/****/

	src_file = src_file_join = des_file = NULL;
	join_offset = 0;

	memset(&p, 0, sizeof(PIC_PARM));    /* important: set all default values 0 */
		/* ALSO important -- following must be set even for PegasusQuery */
		/* beginning version 13 */
	p.ParmSize = sizeof(PIC_PARM);
	p.ParmVer = CURRENT_PARMVER;
	p.ParmVerMinor = 1;
#if NOCO
	defer_status = 0;
	p.DeferFn = &defer_function;
#endif

	if(src_name_join != NULL)
		if(check1(!orient && !requant && !crop_flg,"Can't reorient, requant or crop while joining")) goto quit;


	/*  Open the JPEG file */
	src_file = fopen(src_name, "rb");
	if(check1(src_file != NULL, "Could not open %s", src_name)) goto quit;
	printf("Opened file %s.\n", src_name);


	/*  Open other JPEG file if joining */
	if(src_name_join != NULL)
	{
		src_file_join = fopen(src_name_join, "rb");
		if(check1(src_file_join != NULL, "Could not open %s", src_name_join)) goto quit;
		printf("Opened file %s.\n", src_name_join);
	}

	/*  Allocate GetBuff and place into it the information to be queried */
	if(num_loops > 1)
	{ /* allocate a full_size buffer  */
		get_buff_size = file_size(src_file) + 2;
		if(put_buff_size < get_buff_size << 1)
			put_buff_size = get_buff_size << 1;
	}
	if(src_name_join != NULL)
	{
		join_offset = file_size(src_file_join);
		get_buff_size += join_offset;
	}
	p.Get.Start = (BYTE *) malloc(get_buff_size);
	if(check1(p.Get.Start != NULL, "Out of memory for get buffer")) goto quit;
	p.Get.End = p.Get.Start + get_buff_size;

	/* read in first file if joining */
	if(src_name_join != NULL)
	{
		len = fread(p.Get.Start, sizeof(BYTE), get_buff_size, src_file_join);
		if(check1(ferror(src_file_join) == 0, "Error reading join file")) goto quit;
		if(check1(len == join_offset, "Error reading join file")) goto quit;
	}

	/*  read in header data, at least (of second file if joining) */
	len = fread(p.Get.Start + join_offset, sizeof(BYTE), get_buff_size - join_offset, src_file);
	if(check1(ferror(src_file) == 0, "Error reading input file")) goto quit;
	if(len < get_buff_size - join_offset)
		p.Get.QFlags |= Q_EOF;

	/*  setup output buff */
	p.Put.Start = (BYTE  *) malloc(put_buff_size);
	if(check1(p.Put.Start != NULL, "Out of memory for put buff")) goto quit;
	p.Put.End = p.Put.Start + put_buff_size;

	/* setup output file */
#if PC_WATCOM
	des_file = _fsopen(des_name, "wb", SH_DENYWR);
					/* ^ use _fsopen in watcom so we can make sure the input file
						isn't the same file as the output file.  If it is the same,
						_fsopen will fail with a sharing violation error */
#else
	des_file = fopen(des_name, "wb");
#endif
	if(check1(des_file != NULL,"Could not create %s", des_name)) goto quit;

	p.u.ROR.RegionInfo = NULL;
for(ct = 0;ct < num_loops;++ct)
{
	p.Get.Rear = p.Get.Start + len + join_offset;
	p.Get.Front = p.Get.Start;
	p.Put.Front = p.Put.Rear = p.Put.Start;

#if USE_PEG_QRY
	/* note: PegasusQuery is not ANSI */
	p.u.QRY.BitFlagsReq = QBIT_BICOMPRESSION;
	if(check1(PegasusQuery(&p), "Invalid PegasusQuery")) goto quit;
	memset(&p.u.QRY, 0, sizeof(p.u.QRY));
	if(check1(p.Head.biCompression == BI_PICJ ||
#if PIC2_IN
				p.Head.biCompression == BI_PC2J	||
#endif
#if ELS_CODER_IN
				p.Head.biCompression == BI_JPGE	||
#if PIC2_IN
				p.Head.biCompression == BI_PC2E	||
#endif
#endif
				p.Head.biCompression == BI_JPEG, "Unsupported file type")) goto quit;
#endif

	/*  Set up the output image characteristics. */

	p.ParmSize = sizeof(PIC_PARM);
	p.ParmVer = CURRENT_PARMVER;   p.ParmVerMinor = 1;
#if ELS_CODER_OUT
	p.Op = OP_RORE;
#else
	p.Op = OP_ROR;
#endif
	p.u.ROR.PicFlags = 0;
	p.VisualOrient = orient;
	p.u.ROR.PicFlags = 0;
	if(num_loops == 1)
		p.u.ROR.PicFlags |= PF_YieldPut;
	p.u.ROR.Pad = pad;
	p.u.ROR.KeepColors = keep_colors;
#if ELS_CODER_OUT
	if(els_coder_out)
		p.u.ROR.PicFlags |= PF_ElsCoder;
#endif
	p.u.ROR.JpegType = JT_RAW;
#if PIC2_OUT
	if(pic2_out)
		p.u.ROR.JpegType = JT_PIC2;
#endif
	memcpy(p.KeyField, key, 8);
		memcpy(p.u.ROR.OutputKeyField, outputkey, 8);
	if(requant || ((src_name_join != NULL) && (join_use_requested_quantization)))
	{
		p.u.ROR.Requantize = requant;
		if (QTableName[0] != '\0')
			p.u.ROR.QTableReq = (BYTE PICHUGE *) qtable;
		else
		{
			p.u.ROR.LumFactorReq = lum_opt;
			p.u.ROR.ChromFactorReq =  chrom_opt;
		}
	}
	p.u.ROR.AppsToKeep = apps_to_keep;
	p.u.ROR.RemoveComments = remove_comments;

	if(src_name_join != NULL)
	{
		p.u.ROR.JoinFlags |= JF_DoJoin;
		p.u.ROR.JoinOffset = join_offset;
		if(join_use_requested_quantization)
			p.u.ROR.JoinFlags |= JF_UseRequestedQuantization;
		if(join_left_right)
			p.u.ROR.JoinFlags |= JF_LeftRight;
		if(join_insert)
		{
			p.u.ROR.JoinFlags |= JF_Insert;
			p.u.ROR.InsertTransparencyLum = insert_transparency_lum;
			p.u.ROR.InsertTransparencyChrom = insert_transparency_chrom;
		}
		if(join_second_on_top_left)
			p.u.ROR.JoinFlags |= JF_SecondOnTopLeftInsert;
		if(join_subsampling_from_second)
			p.u.ROR.JoinFlags |= JF_UseSecondSubsampling;
		if(join_quantization_from_second)
			p.u.ROR.JoinFlags |= JF_UseSecondQuantization;
	}
#if(USE_PEG_QRY)
	if(p.Head.biHeight < 1)
	{
		p.Head.biHeight = -p.Head.biHeight;
		/* from now on,p.Head.biHeight is positive. */
	}
	if(regions)
	{
		p.u.ROR.NumRegions = 2;
		p.u.ROR.RegionMapWidth = (p.Head.biWidth + 7) >> 3;
		p.u.ROR.RegionMapHeight = (p.Head.biHeight + 7) >> 3;
		region_x = crop_x >> 3;
		region_y = crop_y >> 3;
		region_endx = (crop_x + crop_w + 7) >> 3;
		region_endy = (crop_y + crop_h + 7) >> 3;
		if(check1(region_x < p.u.ROR.RegionMapWidth &&
							region_y < p.u.ROR.RegionMapHeight &&
							region_endx <= p.u.ROR.RegionMapWidth &&
							region_endy <= p.u.ROR.RegionMapHeight,
			 "Bad region rectangle")) goto quit;
		region_w = region_endx - region_x;
		region_h = region_endy - region_y;
		p.u.ROR.RegionInfo = malloc(8*p.u.ROR.NumRegions + 128*num_tables +
				p.u.ROR.RegionMapWidth * p.u.ROR.RegionMapHeight );
		if(check1(p.u.ROR.RegionInfo != NULL, "Out of memory for RegionInfo")) goto quit;
		region_info_ptr = p.u.ROR.RegionInfo;
		region_info = (REGION_INFO *)region_info_ptr;
		region_info->NumTbls = 255; /* indicates to use qtables from input jpeg for region 0 */
		region_info_ptr += 8; /* word for Lum.,word for Chrom, dword for NumTbls */
		region_info = (REGION_INFO *)region_info_ptr;
		region_info->LumFactor = lum_opt;
		region_info->ChromFactor = chrom_opt;
		region_info->NumTbls = num_tables;
		if (num_tables != 0)
			memcpy(&(region_info->QTbls[0]),region_qtable,num_tables*128);
		p.u.ROR.RegionMapOffset = 8*p.u.ROR.NumRegions + 128*num_tables;
		bptr = p.u.ROR.RegionInfo + p.u.ROR.RegionMapOffset;
		memset(bptr,1,p.u.ROR.RegionMapWidth * p.u.ROR.RegionMapHeight); /* background has index 1 */
		bptr += (region_y * p.u.ROR.RegionMapWidth) + region_x;
		for(k = 0;k < region_h;++k)
		{
			memset(bptr,0,region_w); /* rectangle of interest has index 0 */
			bptr += p.u.ROR.RegionMapWidth;
		}
	}
#endif



/*p.Head.biBitCount = 24; // temp, while not using PegasusQuery */



	if(crop_flg)
	{
		p.Flags |= F_Crop;
		if(crop_w == 0)
			crop_w = 65535; /* init will cut this back to full width */
		if(crop_h == 0)
			crop_h = 65535;
		p.CropWidth = crop_w;
		p.CropHeight = crop_h;
	}
	p.CropXoff = crop_x; /* used also for inserting */
	p.CropYoff = crop_y;


#if	NOCO
	/*  Initialize Jpeg decompression */
	res = Pegasus(&p, REQ_INIT);
	if(check1(defer_status >= 0, "Error %d in DeferFn.", defer_status)) goto quit;
	if(check1(res != RES_ERR, "Error number %d in Pegasus.",p.Status)) goto quit;
	if(check1(p.Status >= 0, "Error %d in Pegasus.", p.Status)) goto quit;
	if (p.Status > 0)  printf("Status %d in Pegasus Init.\n", p.Status);
	if(p.Status == ERR_JUNK_BYTES_IN_HEADER)
		printf("Junk bytes found in header were skipped over.\n");

	/*  Decompress the file. */
	res = Pegasus(&p, REQ_EXEC);
/*	if(check1(defer_status >= 0, "Error %d in DeferFn.", defer_status)) goto quit; */
/*	check1(res != RES_ERR, "Error number %d in Pegasus.",p.Status); output what you can */

	/* Let Pegasus close things(in seq. jpeg, everything is already closed, */
	/* but this would not necessarily be true for progressive) */
	/* res = Pegasus(&p,REQ_TERM); // This can only return RES_DONE, and */
	/* does not change p->Status. Not needed in seq. */

	if (p.Status)  printf("Status %d in Pegasus.\n", p.Status);

#else

	/*  Initialize Jpeg decompression */
	local_status = 0;
	res = Pegasus(&p, REQ_INIT);
	while (res != RES_DONE)
	{
		if (res == RES_GET_NEED_DATA) {
			local_status = read_file(&p);
		} else if (res == RES_PUT_DATA_YIELD) {
			if(num_loops == 1)
				local_status = copy_to_file(&p);
		} else if (res == RES_PUT_NEED_SPACE) {
			if(check1(num_loops == 1,"output buffer too small to do loops")) goto quit;
			local_status = copy_to_file(&p);
		} else if (res == RES_ERR) {
			if(check1(FALSE, "Error number %d ",p.Status)) goto quit;
		} else {
			if(check1(FALSE, "Unexpected or unknown response %d ", res)) goto quit;
		}
		if(check1(p.Status >= 0, "Error %d in Pegasus", p.Status)) goto quit;
		if(check1(local_status >= 0, "Error %d in Pegasus", local_status)) goto quit;
		if (p.Status > 0)  printf("Status %d in Pegasus.\n", p.Status);
		res = Pegasus(&p, REQ_CONT);
	}
	if(check1(p.Status >= 0, "Error %d in Pegasus", p.Status)) goto quit;
	if (p.Status > 0)
		printf("Status %d in Pegasus Init.\n", p.Status);
	if(p.Status == ERR_JUNK_BYTES_IN_HEADER)
		printf("Junk bytes found in header were skipped over.\n");


	/*  Convert the file. */
	res = Pegasus(&p, REQ_EXEC);
	while (res != RES_DONE)
	{
		if (res == RES_GET_NEED_DATA)
			local_status = read_file(&p);
		else if (res == RES_PUT_NEED_SPACE)
		{
			if(check1(num_loops == 1,"output buffer too small to do loops")) goto quit;
			local_status = copy_to_file(&p);
		}
		else if (res == RES_PUT_DATA_YIELD)
		{
			if(num_loops == 1)
				local_status = copy_to_file(&p);
		}
		else if (res == RES_POKE)
		{
			/* write out remainder of put buffer, if any -- there won't
					be a poke until after pack has output everything.
					flushing here saves us having to remember the current
					file position so we can seek back for the final write */
			if ( p.Put.Rear > p.Put.Front )
			{
				len = p.Put.Rear - p.Put.Front;
				if(check1(fwrite(p.Put.Front,sizeof(BYTE),len,des_file) == len,
						"output file write error")) goto quit;
				p.Put.Front = p.Put.Rear;     /* it's empty now */
			}
			else if ( p.Put.Rear < p.Put.Front )
				{
				len = p.Put.End - p.Put.Front;
				if(check1(fwrite(p.Put.Front,sizeof(BYTE),len,des_file) == len,
						"output file write error")) goto quit;
				len = p.Put.Rear - p.Put.Start;
				if(check1(fwrite(p.Put.Start,sizeof(BYTE),len,des_file) == len,
						"output file write error")) goto quit;
        p.Put.Front = p.Put.Rear;     /* it's empty now */
        }
      /* else Rear == Front and there's nothing left to write */
			if(check1(fseek(des_file, p.SeekInfo, SEEK_SET) == 0,
					"output file seek error")) goto quit;
			len = p.Put.RearEnd - p.Put.FrontEnd;
			if(check1(fwrite(p.Put.FrontEnd, sizeof(BYTE), len, des_file) == len,
					"output file write error")) goto quit;
		}
		else if (res == RES_YIELD)
			;
		else if (res == RES_ERR)
			break; /* output what you can. check(FALSE, "Error number %d ",p.Status); */
		else
			if(check1(FALSE, "Unexpected or unknown response %d ", res)) goto quit;
		if(local_status < 0)
    	break;
		res = Pegasus(&p, REQ_CONT);
	}
	if (p.Status)  printf("Status %d in Pegasus.\n", p.Status);
	Pegasus(&p, REQ_TERM);
#endif

	if(p.u.ROR.RegionInfo != NULL)
	{
		free(p.u.ROR.RegionInfo);
		p.u.ROR.RegionInfo = NULL;
	}
}
	if(p.Status == ERR_JUNK_BYTES_IN_HEADER)
		printf("Junk bytes found in header were skipped over.\n");
	if(p.Status == ERR_JUNK_BYTES_BEFORE_RESTART)
		printf("Junk bytes found before restart marker(s) were skipped over.\n");
	if(p.Status == ERR_RESTART_ATTEMPT_AFTER_BAD_DATA)
		printf("Bad data or unexpected end of data in entropy segment, restart attempted.\n");
#if NOCO
	if (defer_status)  printf("defer status %d in Pegasus.\n", defer_status);
#else
	if (local_status)  printf("local status %d in Pegasus.\n", local_status);
#endif
#if REQUANT
	if(p.u.ROR.Requantize && !p.u.ROR.RequantizationDone)
		printf("\nFile was not requantized.\n");
#endif

	/*  copy output buffer to file (if not already done) */
	/* We are not wrapping queue, so Rear >= Front always. */

	if( (len = p.Put.Rear - p.Put.Front) > 0)
		if (fwrite(p.Put.Front, sizeof(BYTE), len, des_file) < len)
			if(check1(FALSE, "error writing output file")) goto quit;

	printf("Converted file %s to %s.\n", src_name, des_name);

	/*  Close files, free memory. */
quit:
	if (src_file != NULL)
		fclose(src_file);
	if (src_file_join != NULL)
		fclose(src_file_join);
	if (des_file != NULL)
		fclose(des_file);

	if(p.Put.Start != NULL)
	{
		free(p.Put.Start);
		p.Put.Start = NULL;
	}
	if(p.Get.Start != NULL)
	{
		free(p.Get.Start);
		p.Get.Start = NULL;
	}
	if(p.u.ROR.RegionInfo != NULL)
	{
		free(p.u.ROR.RegionInfo);
		p.u.ROR.RegionInfo = NULL;
	}
	return (p.Status);
}