This is tifftomac.c in view mode; [Download] [Up]
/* tifftomac.c - tiff file to MacPaint converter Written by Bill Spitzak Converts the input files to MacPaint format. If there are more than two colors, all the even ones turn black and all the odd ones turn white. */ #include <ansi.h> #define movmem(a,b,c) memmove(b,a,c) #define fill(a,b,c) memset(a,c,b) /*================ Code to read a memory-mapped .tiff file: ===============*/ typedef struct { short byteorder; /* 4949=LSB first, 4D4D=MSB first */ short version; /* 42 */ long ifdoffset; /* first IFD directory */ } tiffheader; /* an ifd looks like this: short count; ifdentry entries[count]; long ifdoffset; (next ifd) */ typedef struct { short tag; /* name of the field as a number */ short type; /* type of data */ long length; /* number of elements */ long value; /* data or offset to data if >4 bytes */ } ifdentry; /* types: */ #define TIFFBYTE 1 #define TIFFASCII 2 #define TIFFSHORT 3 #define TIFFLONG 4 #define TIFFRATIONAL 5 /* 2 longs, (double)L1/(double)L2 */ #define TIFFSIZEOF(t) ("\1\1\1\2\4\10"[t]) /* Return the first ifd directory in a mapped .tiff file: */ void *tiffFirstTable(void *map) { int i = ((tiffheader *)map)->ifdoffset; return (i ? map+i : 0); } /* Return the ifd of the next directory in a mapped .tiff file: */ void *tiffNextTable(void *map, void *table) { int i = *(int *)(table+2+*(short *)table*sizeof(ifdentry)); return(i ? map+i : 0); } /* Get a pointer out of a table */ void *tiffpointer(void *map,void *table,int tag) { int j; ifdentry *e; for (j = *(short *)table, e = (ifdentry *)(table+2); j--; e++) if (e->tag == tag) { if (e->length*TIFFSIZEOF(e->type)>4) return(map+e->value); else return(&e->value); } return(0); } /* Get integer constants out of table. Returns the first integer if there is an array of them. Returns garbage if not long or short! */ int tifflookup(void *map,void *table,int tag,int dflt) { int j; ifdentry *e; long *p; for (j = *(short *)table, e = (ifdentry *)(table+2); j--; e++) if (e->tag == tag) { if (e->length*TIFFSIZEOF(e->type)>4) p = (map+e->value); else p = &e->value; if (e->type==TIFFSHORT) return(*(short *)p); return(*p); } return(dflt); } /*=================== Mac Paint writer =======================*/ /* fixed page size in MacPaint file: */ #define BYTESLINE (576/8) #define LINESPAGE 720 packwrite(FILE *f,char *b,int l) { char *run; while (l>0) { run = b; while (l && *b==*run && b-run<128) {b++; l--;} if (b-run > 1) { fputc(-(b-run-1),f); fputc(*run,f); } else { while (l && !(*b==*(b+1) && *b==*(b+2)) && b-run<128) {b++; l--;} fputc(b-run-1,f); while (run<b) {fputc(*run,f); run++;} } } } /* library routines needed: */ int min(a,b) register int a, b; {return((a>b)? b : a);} char *getname(char *cptr) { char *stop; stop=cptr+strlen(cptr); while (--stop>=cptr && *stop!='/'); return(stop+1); } long filelength(int handle) { long ltmp, ltmp2; ltmp=lseek(handle,0L,1); ltmp2=lseek(handle,0L,2); lseek(handle,ltmp,0); return(ltmp2); } char *setext(char *name,char *ext,int force) { char *cptr, *c1; cptr = c1 = name + strlen(name); while (--cptr > name) { if (*cptr == '.') {if (!force) return(name); c1 = cptr; break;} if (*cptr == '/') break; } *c1++ = '.'; strcpy(c1,ext); return(name); } /****/ convert(void *map,char *tname) { FILE *f; int x,y; char *p,*q,fname[80]; char line[BYTESLINE]; void *table = tiffFirstTable(map); int BitsPerSample = tifflookup(map,table,258,1); int SamplesPerPixel = tifflookup(map,table,277,1); int ImageWidth = tifflookup(map,table,256,0); int ImageLength = tifflookup(map,table,257,0); int *StripOffsets = (int *)(tiffpointer(map,table,273)); strcpy(fname,(char *)getname(tname)); setext(fname,"PNTG",1); f = fopen(fname,"w"); /* write empty MacPaint header: */ for (x=0; x<512; x++) fputc(0,f); p = (char *)(map+StripOffsets[0]); if (ImageLength > LINESPAGE) ImageLength = LINESPAGE; for (y=0; y<ImageLength; y++) { x = min((ImageWidth+7)/8,BYTESLINE); if (BitsPerSample > 1) { int n,m,z; char *p1 = p; for (q=line; q<line+x;) { z = 0; for (n=7,m=8-BitsPerSample; n>=0; n--) { if (n>m) z |= ((~*p)&(1<<m))<<(n-m); else z |= ((~*p)&(1<<m))>>(m-n); if ((m-=BitsPerSample)<0) {p++; m = 8-BitsPerSample;} } *q++ = z; } p = p1+(BitsPerSample*ImageWidth+7)/8; } else for (q=line; q<line+x;) *q++ = ~(*p++); fill(line+x,BYTESLINE-x,0); packwrite(f,line,BYTESLINE); } for (; y<LINESPAGE; y++) { fill(line,BYTESLINE,0); packwrite(f,line,BYTESLINE); } fclose(f); } main(int argc,char **argv) { int i; int fd,length; void *map; char *fname; extern int task_self_; if (argc < 2) { puts("Convert a .tiff file to MacPaint format."); exit(0); } for (i = 1; i < argc; i++) { fname = argv[i]; fd = open(fname,0); if (fd<0) {printf("%s : %s\n",fname,strerror(fd)); continue;} length = filelength(fd); map_fd(fd,0,&map,1,length); if (((tiffheader *)map)->version == 42) convert(map,fname); else printf("%s is not a .tiff file.\n",fname); close(fd); vm_deallocate(task_self_,map,length); } }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.