[comp.sources.amiga] v90i172: iff2sixel 1.21 - convert IFF ILBM to SIXEL , Part01/01

Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator) (06/04/90)

Submitted-by: Tony Kennedy <KENNEDY%WWPACS%dupont.com@RELAY.CS.NET>
Posting-number: Volume 90, Issue 172
Archive-name: util/iff2sixel-1.21/part01

This program takes a AMIGA IFF ILBM file and converts it to a SIXEL file
to be displayed on DIGITAL EQUIPMENT CORP. VT240, VT241, VT340
terminals.
              
This version will handle only 16 colors for a VT340 and 4 colors for a
VT240. It does no color compression, so all input files must be 16
colors or less for a 340, 4 colors or less for a 240. Or, up to 64
colors for a printer.

If the display is a VT240/241 then the resolution is set to 640X200. If
it's a 340 then the res is 640X400.  PRINT gives a straight pixel for
pixel representation.

I tried to make it a generic as possible so you can compile it under
what ever environment you please.  If you do it under VMS you will need
to define IFF2SIXEL as a foreign command i.e.  $ iff2sixel :==
$mydir:iff2sixel otherwise you can't use command line args.

#!/bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 1)."
# Contents:  iff2sixel.c
# Wrapped by tadguy@xanth on Sun Jun  3 18:08:11 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'iff2sixel.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'iff2sixel.c'\"
else
echo shar: Extracting \"'iff2sixel.c'\" \(20888 characters\)
sed "s/^X//" >'iff2sixel.c' <<'END_OF_FILE'
X/*****************************************************************************/
X/*									     
X	Program  : IFF2SIXEL.C
X
X	Author   : Tony Kennedy
X		   Internet address: kennedam%wwps@dupont.com@relay.cs.net
X
X	Purpose  : This program takes a AMIGA IFF ILBM file and converts
X		   it to a SIXEL file to be displayed on DIGITAL EQUIPMENT
X		   CORP. VT240, VT241, VT340 terminals. 
X                                 
X		   This version will handle only 16 colors for a VT340 and
X		   4 colors for a VT240. It does no color compression, so
X		   all input files must be 16 colors or less for a 340,
X		   4 colors or less for a 240. Or, up to 64 colors for a
X		   printer.
X
X		   If the display is a VT240/241 then the resolution
X		   is set to 640X200. If it's a 340 then the res is 640X400.
X		   PRINT gives a straight pixel for pixel representation.
X
X		   I tried to make it a generic as possible so you can 
X		   compile it under what ever environment you please.
X		   If you do it under VMS you will need to define IFF2SIXEL
X		   as a foreign command i.e.  $ iff2sixel :== $mydir:iff2sixel
X		   otherwise you can't use command line args.
X
X	Usage    : iff2sixel <input_file> <output_file> <VT240 | VT340 | PRINT>
X
X	Comments : This program is Freely Distributable. You may
X		   use it for any non-commercial uses.  
X                   (If anybody hacks at this please send me a copy.)
X
X	Acknowledgements : Thanks to...
X
X			 	Carter Brock for the SHOW_IFF program I used
X				to figure out how to read an IFF file.
X
X				Mark Thompson and Steve Berry for the IFF2SUN
X				program I used to figure out how to interpret
X				the bitplanes.
X
X				Barry Young for his help with SIXEL formats.
X
X				Daniel Jay Barrett for his switching bytes
X				hacks.
X
X				All the people at Dupont who tested it on 
X				their pictures. (Hi Mike!)
X
X	Limitations : This won't do HAM. When I figure it out
X		      I'll put that in too.
X		      Won't do any color compression.
X		      I had some trouble getting this to run on the Amiga.
X		      It needs a REALLY big stack.  Next time I rewrite it,
X		      I'll do something about that.
X
X	Versions:		Revisions : 
X	
X	1.0  3/1/89 		Original program.
X	1.1  5/5/89		Modified to read Deluxe Paint III files.
X				More robust IFF header read routines.
X	1.2  7/14/89		Changed Argument line routine.
X				Changed SixelLine Array to do one line at
X				a time instead of the whole thing at once.
X				Added #define H_LINES, V_LINES, N_COLORS
X				Changed all unsigned short to short.
X	1.21 4/4/90		Added Halfbrite, overscan, 7 bit control codes.
X				Checks for PAL. Printer codes for LJ250 ink jet
X				printer.
X*/
X/*****************************************************************************/
X
X#include <stdio.h>
X#include <math.h>
X
X#define Sixel_base 63
X#define DCS        144
X#define ST         156
X#define QUOTE      34
X
X#define LoRes  1
X#define LoLace 2
X#define HiRes  3
X#define HiLace 4
X
X#define X320x200 10
X#define Y320x200 11
X#define X320x400 20
X#define Y320x400 11
X#define X640x200 5
X#define Y640x200 11
X#define X640x400 10
X#define Y640x400 11
X
X#define VT240_LoRes  1
X#define VT240_LoLace 2
X#define VT240_HiRes  3
X#define VT240_HiLace 4
X#define VT340_LoRes  5
X#define VT340_LoLace 6
X#define VT340_HiRes  7
X#define VT340_HiLace 8
X
X#define H_LINES 1500
X#define V_LINES 600
X#define N_COLORS 64
X
X#define V_LACE 400
X#define V_NOLACE 200
X#define V_LACE_PAL 512
X#define V_NOLACE_PAL 256 
X#define H_HIRES 640
X#define H_LORES 320
X
X#define SUCCESS 1
X
X typedef unsigned char ID_type[4];
X struct ChunkType
X	{
X		ID_type Ident ;
X		long    ChunkSize ;
X	} ;
X struct ChunkType chunk ;
X
X typedef struct 
X	{
X		unsigned char red, green, blue;
X	} ColorRegType;                   
X
X unsigned char BitPlaneArray[480][6][128];   /* vert pos, plane, width pos*/  
X unsigned char PixelArray[480][H_LINES];     /* vert posit, horiz posit   */
X char	       SixelLine[N_COLORS][H_LINES]; /* color,horizontal posit.   */
X int	       vert, horz, s_vert, v_bit;
X
X/********************************************************************
X
X	This function decompresses the IFF file. I got the algorithm
X	from Mark and Steve who got it from Leo (The Great Caped One).
X
X********************************************************************/
X
X int decompress_planes(nplanes,width,height,inp_file)
X
X short nplanes,width,height;
X FILE *inp_file;
X 
X {
X   long h,p,count,BytesPerRow;
X   char len;
X   unsigned char byte;
X
X   for (h=0;h<height;h++)
X     {
X	for (p=0;p<nplanes;p++)
X	  {
X	     count = 0;
X	     BytesPerRow=width/8;
X	     while(BytesPerRow>0)
X		{
X		  if ((len = getc(inp_file)) >= 0)
X		     {
X			BytesPerRow -= ++len;
X			fread(&BitPlaneArray[h][p][count],len,1,inp_file);
X			count += len;
X		     }
X		  else 
X		     if (len < 0)
X		     {
X			len = -len + 1;
X			BytesPerRow -= len;
X			byte = getc(inp_file);
X			while (--len >= 0)
X				BitPlaneArray[h][p][count++] = byte;
X		     }
X		}
X	     if (BytesPerRow) printf("Compression is corrupt.\n");
X	}
X     }
X  }
X
X/********************************************************************
X
X	Since the VAX reads shorts and longs backwards we've got to 
X	flip them around...
X
X********************************************************************/
X
X#ifdef VAX
X
Xshort flip_byte_short(s)
X
X  short s;
X  {
X	short hib,lob;
X
X	lob = (s & 255);
X	hib = ((s >> 8) & 255);
X	return ((lob << 8) + hib);
X  }
X
Xlong flip_bytes_long(l)
X
X  long l;
X  {
X	short low,hiw;
X
X	low = (l & 65535);
X	hiw = ((l >> 16) & 65535);
X	return ( ((flip_byte_short(low) << 16) + flip_byte_short(hiw)));
X  }
X#endif
X
X/********************************************************************
X
X	Convert a string to upper case.
X
X********************************************************************/
X
Xchar *upcase(str)
X 
X  char *str;
X
X  {
X	int len, i;
X
X	i=0;
X	len=strlen(str);
X	while(i != len)
X		{
X		  str[i]=toupper(str[i]);
X		  i++;
X		}
X	return str;
X  }
X
X/********************************************************************
X
X	Double the width of the Pixel Array.
X
X********************************************************************/
X
X short double_width(width,height)
X
X  short width,height;
X
X  {
X	short h,w;
X	for (h=0;h<height;h++)
X	  {
X	    for (w=width-1;w>=0;w--)
X		{
X		  PixelArray[h][w * 2] = PixelArray[h][w];
X		  PixelArray[h][(w * 2)+1] = PixelArray[h][w];
X		}                       
X	  }
X	  return (width * 2);
X  }
X
X/********************************************************************
X
X	Double the height of the Pixel array.
X
X********************************************************************/
X
X short double_height(width,height)
X
X  short width,height;
X
X  {
X	short h,w;
X	for (w=0;w<width;w++)
X	  for (h=height-1;h>=0;h--)
X		{
X		  PixelArray[h * 2][w]=PixelArray[h][w];
X		  PixelArray[(h * 2)+1][w]=PixelArray[h][w];
X		}
X	return (height * 2);
X  }
X
X/********************************************************************
X
X	Halve the height of the Pixel Array. This is gonna make the
X	picture look pretty ugly if you ask me. Only gets done if a
X	picture for a VT240 from an interlace IFF file is being 
X	generated.
X
X********************************************************************/
X
Xshort halve_height(width,height)
X
X  short width,height;
X
X  {
X	short h,w;
X	for (h=0;h<height;h++)
X		for (w=0;w<=width;w++)
X			PixelArray[h][w]=PixelArray[(h * 2)][w];
X
X	return (height/2);
X  }                                            
Xmain (argc,argv)
X
X int argc;
X char **argv[];
X 
X {
X  long num_colors;
X  int stat;
X  long posit,h,w,p,i,j,k,l,m,pixel,v_pos;
X  long w_pos,cnt_100,cnt_10,cnt_1,rep_cnt;
X  char ch, outline[900];
X  unsigned char  color;
X  char *term;
X  FILE *outf,*inf;
X  char start_sixel = DCS;
X  char end_sixel = ST;
X  char quote = QUOTE;
X  int  convert_mode = 0;
X  int  resolution;
X
X  struct BitMapHeaderType
X	{
X		short width, height;
X		short          org_x, org_y;
X		unsigned char  NumPlanes, Mask, Compression, pad;
X		unsigned short TransColor;
X		unsigned char  X_Asp, Y_Asp;
X		unsigned short PageWid, PageHeight;
X	} ;
X  struct BitMapHeaderType bmhd;
X                              
X  ColorRegType CMap[N_COLORS];
X  
X/*********************************************************************
X
X First, get all the needed info from the user...			
X  			
X	Input file, Output file, Type of terminal to create a file for.
X
X*********************************************************************/
X                                 
X  switch (argc)
X    {                                                   
X	case 4:
X		
X		inf = fopen(argv[1],"r");
X
X		    if (inf == NULL) {
X      			printf("Input file can't be opened.\n");
X      			exit(0); }
X                                                                          
X		outf = fopen(argv[2],"w");
X
X    		if (outf == NULL) {
X      			printf("Output can't be opened.\n");
X			close(inf);
X      			exit(0); }        
X
X		term = argv[3];
X                                                             
X              	if  ((strcmp(upcase(term),"VT240",5) != 0) &&
X              	     (strcmp(upcase(term),"VT340",5) != 0) &&
X		     (strcmp(upcase(term),"PRINT",5) != 0))
X		     {
X			printf("Not a valid terminal type. VT240 or VT340.\n");
X			close(inf);close(outf);
X			exit(0);
X		     }                                  
X/*		resolution = atoi(argv[4]);
X		if ((resolution<1)||(resolution>4)) {
X		  printf("1 - LoRes\n 2 - LoLace\n3 - HiRes\n4 - HiLace\n");
X		  close(inf);close(outf);
X		  exit(0);}
X*/
X		break;
X
X	default:                     
X                                                        
X  	  printf("\nIFF2Sixel Conversion Program.\n");
X  	  printf("  V1.21 4/90 Tony Kennedy\n");    
X	  printf("\nUSAGE : IFF2Sixel <input> <output> <VT240|VT340|PRINT>\n");
X	  exit(0);             
X                                                        
X    }
X                        
X	                                                                  
X
X/*********************************************************************
X
X	Ok. Now read in the IFF file...
X
X*********************************************************************/
X
X	
X	stat=fread(chunk.Ident,4,1,inf);
X	if (stat == -1) 
X		{
X			printf("Error reading file.\n");
X			stat=close(inf) ; stat=close(outf);
X			exit(0);
X                }
X	                                 
X
X	while ((strncmp(chunk.Ident,"FORM",4) !=0) && (stat==SUCCESS))
X
X		{
X		stat=fread(&ch,1,1,inf);
X		for (i=0; i < 3; i++)
X			chunk.Ident[i] = chunk.Ident[i+1];
X		chunk.Ident[3]=ch;
X		}                                  
X                                 
X	if (strncmp(chunk.Ident,"FORM",4) != 0) 
X		{
X			printf("Error, not a FORM file.\n");
X			stat=close(inf); stat=close(outf);
X			exit(0);
X		}
X
X	stat=fread(&chunk.ChunkSize,4,1,inf);
X
X	stat=fread(chunk.Ident,4,1,inf);
X                                               
X	while ((strncmp(chunk.Ident,"ILBM",4) !=0) && (stat==SUCCESS)) 
X
X             
X		{
X		stat=fread(&ch,1,1,inf);
X		for (i=0; i < 3; i++)
X			chunk.Ident[i] = chunk.Ident[i+1];
X		chunk.Ident[3]=ch;
X		}                                                      
X	if (strncmp(chunk.Ident, "ILBM",4) !=0) 
X                                               
X		{
X			printf("Error Not an ILBM file.\n");
X	      		stat=close(inf); stat=close(outf);
X			exit(0);
X		}                              
X	stat=fread(chunk.Ident,4,1,inf);
X        
X	while ((strncmp(chunk.Ident,"BMHD",4) !=0) && (stat==SUCCESS))
X
X             
X		{
X		stat=fread(&ch,1,1,inf);
X		for (i=0; i < 3; i++)
X			chunk.Ident[i] = chunk.Ident[i+1];
X		chunk.Ident[3]=ch;
X		}                                                      
X	if (strncmp(chunk.Ident, "BMHD",4) !=0)
X		{
X			printf("Error can't find Bit Map Header.\n");
X	      		stat=close(inf); stat=close(outf);
X			exit(0);
X
X		}                              
X 	stat=fread(&chunk.ChunkSize,4,1,inf);
X
X	stat=fread(&bmhd,20,1,inf);
X             
X	if (stat == -1)
X		{
X			printf("Error failed to get Bit Map information.\n");
X	      		stat=close(inf); stat=close(outf);
X			exit(0);
X		}
X
X
X	stat=fread(chunk.Ident,4,1,inf);
X        
X	while ((strncmp(chunk.Ident,"CMAP",4) !=0) && (stat==SUCCESS))
X
X             
X		{
X		stat=fread(&ch,1,1,inf);
X		for (i=0; i < 3; i++)
X			chunk.Ident[i] = chunk.Ident[i+1];
X		chunk.Ident[3]=ch;
X		}                                                      
X	if (strncmp(chunk.Ident,"CMAP",4) !=0)
X		{
X			printf("Error can't find Color Map.\n");
X	      		stat=close(inf); stat=close(outf);
X			exit(0);
X		}                 
X        stat=fread(&num_colors,4,1,inf);           
X
X#ifdef VAX
X
X	bmhd.width=flip_byte_short(bmhd.width);
X	bmhd.height=flip_byte_short(bmhd.height);
X	bmhd.org_x=flip_byte_short(bmhd.org_x);
X	bmhd.org_y=flip_byte_short(bmhd.org_y);
X	bmhd.TransColor=flip_byte_short(bmhd.TransColor);
X	bmhd.PageWid=flip_byte_short(bmhd.PageWid);
X	bmhd.PageHeight=flip_byte_short(bmhd.PageHeight);
X	num_colors=flip_bytes_long(num_colors);
X
X#endif
X
X/********************************************************************
X
X	define conversion mode.  This is really convoluted because 
X	there doesn't seem to be a consistant way of telling what 
X	resolution a pictures is in.  This checks Page Width and 
X	Height, and XY aspect ratio.
X
X********************************************************************/
X                                  
X
X	if ((bmhd.PageWid==H_LORES)&&
X	    ((bmhd.PageHeight==V_NOLACE)||(bmhd.PageHeight==V_NOLACE_PAL))
X	   ) 
X		resolution=LoRes;
X	if ((bmhd.PageWid==H_LORES)&&
X	     ((bmhd.PageHeight==V_LACE)||(bmhd.PageHeight==V_LACE_PAL))
X	    )                        
X		resolution=LoLace;
X	if ((bmhd.PageWid==H_HIRES)&&
X	    ((bmhd.PageHeight==V_NOLACE)||(bmhd.PageHeight==V_NOLACE_PAL))
X	   )
X		resolution=HiRes;
X	if ((bmhd.PageWid>=H_HIRES)&&
X	     ((bmhd.PageHeight>=V_LACE)||(bmhd.PageHeight>=V_LACE_PAL))
X	    )                   
X		resolution=HiLace;                        
X
X
X	if ((bmhd.X_Asp==X320x200)&&
X	    (bmhd.Y_Asp==Y320x200)) 	resolution=LoRes;
X
X	if ((bmhd.X_Asp==X320x400)&&
X	    (bmhd.Y_Asp==Y320x400)) 	resolution=LoLace;
X
X	if ((bmhd.X_Asp==X640x200)&&
X	    (bmhd.Y_Asp==Y640x200)) 	resolution=HiRes;
X
X	if ((bmhd.X_Asp==X640x400)&&
X	    (bmhd.Y_Asp==Y640x400)&&
X	    (bmhd.PageHeight>=V_LACE))	resolution=HiLace;
X
X
X	if  ((strcmp(upcase(term),"VT240",5) == 0) &&  
X	     (resolution==LoRes)) convert_mode=VT240_LoRes;
X
X	if  ((strcmp(upcase(term),"VT240",5) == 0) &&  
X	     (resolution==LoLace)) convert_mode=VT240_LoLace;
X
X	if  ((strcmp(upcase(term),"VT240",5) == 0) &&  
X	     (resolution==HiRes)) convert_mode=VT240_HiRes;
X
X	if  ((strcmp(upcase(term),"VT240",5) == 0) &&  
X	     (resolution==HiLace)) convert_mode=VT240_HiLace;
X
X	if  ((strcmp(upcase(term),"VT340",5) == 0) &&  
X	     (resolution==LoRes)) convert_mode=VT340_LoRes;
X
X	if  ((strcmp(upcase(term),"VT340",5) == 0) &&  
X	     (resolution==LoLace)) convert_mode=VT340_LoLace;
X
X	if  ((strcmp(upcase(term),"VT340",5) == 0) &&  
X	     (resolution==HiRes)) convert_mode=VT340_HiRes;
X
X	if  ((strcmp(upcase(term),"VT340",5) == 0) &&  
X	     (resolution==HiLace)) convert_mode=VT340_HiLace;
X
X        if  (strcmp(upcase(term),"PRINT",5) == 0)
X				  convert_mode=VT340_HiLace;
X        
X	
X
X	if (!convert_mode) 
X		{
X		printf("IFF picture is an irregular size.\n");
X		printf("Converting pixel to pixel representation.\n");
X		convert_mode=VT340_HiLace;
X   		}
X
X
X	num_colors=num_colors/3;                         
X	stat=fread(CMap,(num_colors * 3),1,inf);
X                
X        if ( (num_colors > N_COLORS) ||
X	     ((num_colors > 4) && (strcmp(upcase(term),"VT240",5) == 0))
X	   )
X
X		{
X		   printf("File has too many colors for this conversion.\n");
X		   close(inf);
X		   close(outf);
X		   exit(0);
X		}
X	if (bmhd.NumPlanes == 6) {
X		for (i=0;i<32;i++)
X		  {
X			CMap[i+32].red = CMap[i].red>>1;
X			CMap[i+32].blue = CMap[i].blue>>1;
X			CMap[i+32].green = CMap[i].green>>1;
X		  }
X		num_colors = 64;
X				}
X
X
X/********************************************************************
X
X	Skip everything till we find the BODY.
X
X********************************************************************/
X                                         
X	stat=fread(chunk.Ident,4,1,inf); 
X	while (strncmp(chunk.Ident,"BODY",4) !=0)  
X		{
X		stat=fread(&ch,1,1,inf);
X		for (i=0; i < 3; i++)
X			chunk.Ident[i] = chunk.Ident[i+1];
X		chunk.Ident[3]=ch;
X		}                                  
X                                 
X
X	stat=fread(chunk.Ident,4,1,inf); /* body length */
X
X
X/********************************************************************
X
X	Now read the bit planes in.
X
X********************************************************************/
X
X	if (bmhd.Compression == 1)
X		decompress_planes(bmhd.NumPlanes,bmhd.width,bmhd.height,inf);
X	else
X
X		for (h = 0;h<bmhd.height;h++)
X			for (p = 0;p<bmhd.NumPlanes;p++) 
X				{
X				 for (w = 0;w<bmhd.width/8;w++) 
X					{
X					 if (feof(inf)) continue;
X					 read(inf,BitPlaneArray[h][p][w],1);
X			                }
X                                }
X	close(inf);
X
X/********************************************************************
X
X	Translate bit planes to pixel color values.
X
X********************************************************************/
X
X    	for (h = 0;h<bmhd.height;h++)
X	 {
X	 w_pos = 0;
X	 for (w=0;w<bmhd.width/8;w++)
X	   {                                                   
X	    pixel = 0;    
X	    for (i=7;i>=0;i--)
X	      {
X	       
X		for (p=0;p<bmhd.NumPlanes;p++)
X		  pixel = ((((1 << i) & BitPlaneArray[h][p][w])>>i)<<p)|pixel;
X	       
X		PixelArray[h][w_pos++] = (unsigned char)(pixel); 
X		pixel = 0;
X	      }                                              
X	   }
X	 }	
X
X/********************************************************************
X
X	Convert to screen size.
X
X********************************************************************/
X
X	switch(convert_mode)
X
X		{
X		     case VT240_LoRes : 
X			  bmhd.width = double_width(bmhd.width,bmhd.height);
X                          break;                        
X
X	             case VT240_LoLace :
X			  bmhd.height = halve_height(bmhd.width,bmhd.height);
X			  bmhd.width = double_width(bmhd.width,bmhd.height);
X			  break;
X		     
X		     case VT240_HiRes : 
X			  break;
X	                  
X		     case VT240_HiLace :
X			  bmhd.height = halve_height(bmhd.width,bmhd.height);
X			  break;
X
X		     case VT340_LoRes :
X			  bmhd.width = double_width(bmhd.width,bmhd.height);
X			  bmhd.height = double_height(bmhd.width,bmhd.height);
X			  break;
X
X		     case VT340_LoLace :
X			  bmhd.width = double_width(bmhd.width,bmhd.height);
X                          break;                        
X
X		     case VT340_HiRes :
X			  bmhd.height = double_height(bmhd.width,bmhd.height);
X			  break;
X
X		     case VT340_HiLace :
X			  break;
X
X		}
X                
X/********************************************************************
X
X	Convert Pixels to Sixels.
X
X********************************************************************/
X
X	vert=bmhd.height;
X	horz=bmhd.width;
X	v_bit = 0;
X                    		
X                                                   
X/********************************************************************
X
X	Compress Sixels and write to file.
X
X********************************************************************/
X
X	
X	vert = bmhd.height/6;
X
X/*	Write Sixel start code. */
X
X	fprintf(outf,"%cP;1;8;q%c1;1;;\n",27,quote);
X
X/*	Write color map. */
X
X	for (color=0;color<num_colors;color++)
X	  {
X		CMap[color].red   = (CMap[color].red * 100)/255;		
X		CMap[color].green = (CMap[color].green * 100)/255;
X		CMap[color].blue  = (CMap[color].blue * 100)/255;
X		fprintf(outf,"#%d;2;%d;%d;%d\n",color,
X		        CMap[color].red,CMap[color].green,CMap[color].blue);
X
X	  }
X	  fprintf(outf,"\n");
X
X
X/* 	Compress and write Sixels. */
X
X	v_pos = 0;
X
X	for (s_vert=0;s_vert <= vert;s_vert++)
X	 {
X        
X	for (i=0;i<N_COLORS;i++)
X		{
X		   for (j=0;j<horz;j++)
X			SixelLine[i][j] = 0;
X		}
X    
X	for (i=0;i<6;i++)
X	   {        
X		for (j=0;j<horz && v_pos<bmhd.height;j++)
X		   {
X		    color = PixelArray[v_pos][j];                               
X		    SixelLine[color][j] |= (int)pow(2,i);
X		   }      
X		v_pos++;
X	   }
X                    
X
X	   for (color=0;color<num_colors;color++)
X	    {
X
X	      for (j=0;j<horz;j++)                                
X			SixelLine[color][j] += Sixel_base;
X	      i = 0;
X	      k = 0;
X	      while( i < horz )
X		{
X		   ch = SixelLine[color][i];			
X		   l=i;
X
X		   while ((l < horz) && (ch == SixelLine[color][l]))
X			l++;
X		   rep_cnt = l - i;
X		   if (rep_cnt >= 5)
X			{
X			   cnt_100 = rep_cnt/100;
X			   cnt_10  = (rep_cnt-(cnt_100 * 100))/10;
X			   cnt_1   = (rep_cnt-((cnt_100 * 100)+(cnt_10 * 10)));
X			   outline[k] = 33; /* Exclamation mark */
X			   outline[++k] = cnt_100 + 48;
X			   outline[++k] = cnt_10  + 48;
X			   outline[++k] = cnt_1   + 48;
X			   outline[++k] = SixelLine[color][l-1];
X			   k++;
X			   i=l;
X			}
X		   else
X			{
X			   for (m=0;m<=(l-1)-i;m++)
X				   outline[k+m]=SixelLine[color][l-1];
X			   k += (l-i);
X			   i=l;
X			}
X		}         
X		outline[k]=0;
X		if (strcmp(outline,"!640?",5))
X		fprintf(outf,"#%d %s$\n",color,&outline); 
X
X	    }
X	    fprintf(outf," - \n");
X	}
X	fprintf(outf,"%c\\\n",27);
X	close(outf);
X     }
END_OF_FILE
if test 20888 -ne `wc -c <'iff2sixel.c'`; then
    echo shar: \"'iff2sixel.c'\" unpacked with wrong size!
fi
# end of 'iff2sixel.c'
fi
echo shar: End of archive 1 \(of 1\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have the archive.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
Mail comments to the moderator at <amiga-request@cs.odu.edu>.
Post requests for sources, and general discussion to comp.sys.amiga.