Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!usc!zaphod.mps.ohio-state.edu!uakari.primate.wisc.edu!xanth!cs.odu.edu!Amiga-Request From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator) Newsgroups: comp.sources.amiga Subject: v90i172: iff2sixel 1.21 - convert IFF ILBM to SIXEL , Part01/01 Message-ID: <12697@xanth.cs.odu.edu> Date: 3 Jun 90 22:08:25 GMT Sender: tadguy@cs.odu.edu Reply-To: Tony Kennedy Lines: 884 Approved: tadguy@cs.odu.edu (Tad Guy) X-Mail-Submissions-To: Amiga@cs.odu.edu X-Post-Discussions-To: comp.sys.amiga Submitted-by: Tony Kennedy 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 '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 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 X#include 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;h0) 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=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=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;h4)) { 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 \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=0;i--) X { X X for (p=0;p>i)<= 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 . Mail comments to the moderator at . Post requests for sources, and general discussion to comp.sys.amiga.