home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
309.lha
/
PBM_PLUS
/
pbm
/
tifftopbm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1980-12-04
|
14KB
|
525 lines
/*
**---------------------------------------------------------------------
** tifftopbm.c
**---------------------------------------------------------------------
**
** Copyright 1988 by Paul J. Emerson
**
** Permission to use, copy, modify, and distribute this software
** and its documentation for any purpose and without fee is
** hereby granted, provided that the above copyright notice
** appear in all copies and that both that copyright notice and
** this permission notice appear in supporting documentation, and
** that the name of Paul J. Emerson not be used in advertising or
** publicity pertaining to distribution of the software without
** specific, written prior permission. Paul J. Emerson makes no
** representations about the suitability of this software for
** any purpose. It is provided "as is" without express or implied
** warranty.
**
** Version 1.4
** Jef Poskanzer (jef@helios.ee.lbl.gov)
** April 1989
**
** Comments
** - Now uses new PBM error handling routine.
**
** Version 1.3
** Lindsay F. Marshall (Lindsay.Marshall@newcastle.ac.uk)
** January 1989
**
** Comments
** - Removed include of malloc.h and added extern for malloc.
**
** Version 1.2
** Jef Poskanzer (jef@rtsg.ee.lbl.gov)
** January 1989
**
** Comments
** - Patch from Mike K. Peterson (mkp@hac2arpa.hac.com) to handle
** MicroTek VersaScan variant.
**
** Version 1.1
** Jef Poskanzer (jef@rtsg.ee.lbl.gov)
** December 1988
**
** Comments
** - Changed name from tiff2pbm to tifftopbm.
** - Changed to use libpbm routines.
**
** Version 1.0
** Paul J. Emerson (ucf-cs!sdgsun!paul)
** December 1988
**
** Comments
** - TIFF Support:
** - Single Bit Plane
** - Black & White (No grey scale or color)
** - Uncompressed TIFF
** - Supports PBM magic number
** - Usage: tifftopbm [-h] tifffile
** -h Dump TIFF file header info to stderr
** This may be helpful in detecting unsuported aspects
** of the TIFF file format.
**
** Notes:
** Compile: cc -O tifftopbm.c -o tifftopbm
**
**---------------------------------------------------------------------
*/
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include "tiff.h"
#include "pbm.h"
#define TRUE 1
#define FALSE 0
main(argc,argv)
int argc;
char *argv[];
{
int fd,
Dump=FALSE;
struct Tiffstruct Tiff;
struct TiffHeader Header;
char fname[255];
char *usage = "[-h] tifffile";
pm_progname = argv[0];
if (argc >= 2)
{
if (!strcmp("-h",argv[1]))
{
Dump = TRUE;
if (argc == 3)
strcpy(fname,argv[2]);
else
{
printf(usage,argv[0]);
exit(1);
}
}
else
strcpy(fname,argv[1]);
if ((fd = open(fname,O_RDONLY)) < 0 )
{
perror(fname);
exit(1);
}
}
else
{
printf(usage,argv[0]);
exit(1);
}
if (readTiff(&Tiff,&Header,fd))
{
if (Dump)
dumpHeader(&Tiff,&Header);
PbmOut(fd,&Tiff);
}
else
pm_error( "readTiff failure", 0,0,0,0,0 );
close(fd);
}
/*
**------------------------------------------------------------------------
** Send image to stdout in PBM format
**------------------------------------------------------------------------
*/
PbmOut(fd,t)
int fd;
struct Tiffstruct *t;
{
register int i, row;
char *bptr;
LONG *cntptr;
LONG *dataptr;
register bit **bits;
extern char *malloc();
bits = pbm_allocarray(t->ImageWidth,t->ImageLength);
dataptr = t->StripOffset;
cntptr = t->SBytesCntOffset;
for (i=0, row=0; i < t->StOffsetCnt; i++, row += t->RowsStrip)
{
lseek(fd,(long) *dataptr,0);
bptr = malloc(*cntptr);
if ( bptr == 0 )
pm_error( "out of memory", 0,0,0,0,0 );
if (read(fd,bptr,*cntptr) != *cntptr)
{
perror("StripOffset read ");
return;
}
PbmDoRow(bptr,*cntptr,bits,row,t->ImageWidth);
free(bptr);
cntptr++;
dataptr++;
}
pbm_writepbm(stdout,bits,t->ImageWidth,t->ImageLength);
}
/*
**------------------------------------------------------------------------
** Output a row in PBM format
**------------------------------------------------------------------------
*/
PbmDoRow(buffer,count,bits,row,cols)
char *buffer;
int count;
bit **bits;
int row, cols;
{
register int i, col;
col = 0;
while (count--)
{
for (i = 0 ; i < 8; i++)
{
bits[row][col++] =
( ( *buffer << i ) & 0x80 ) ? PBM_BLACK : PBM_WHITE;
if ( col >= cols )
{
col = 0;
row++;
}
}
buffer++;
}
}
/*
**------------------------------------------------------------------------
** Read and decode a Tiff header.
** Not all TIFF capabilities are supported. Only single plane bit maps.
**------------------------------------------------------------------------
*/
int
readTiff(T,H,fd)
struct Tiffstruct *T;
struct TiffHeader *H;
int fd;
{
struct IDF idf;
struct IDF_Entry *ptr;
LONG TempRational[2];
#ifdef SYSV
memset((char *)T,0,sizeof(struct Tiffstruct));
#else SYSV
bzero((char *)T,sizeof(struct Tiffstruct));
#endif SYSV
if (read(fd,H,sizeof(struct TiffHeader)) != sizeof(struct TiffHeader))
{
perror("Header ");
return(FALSE);
}
lseek(fd,(long)H->IdfOffset,0);
if (read(fd,&idf.NumEntries,sizeof(SHORT)) != sizeof(SHORT))
{
perror("Idf count ");
return(FALSE);
}
if ((idf.idfptr = (struct IDF_Entry *)
calloc(idf.NumEntries,sizeof(struct IDF_Entry))) == NULL)
{
perror("calloc ");
return(FALSE);
}
if (read(fd,idf.idfptr,idf.NumEntries*sizeof(struct IDF_Entry))
!= idf.NumEntries*sizeof(struct IDF_Entry))
{
perror("Idf count ");
return(FALSE);
}
ptr = idf.idfptr;
while (idf.NumEntries--)
{
switch (ptr->Tag)
{
case 0x00FF:
T->SubFileType = (ptr->ValueOffset >> 16);
break;
case 0x0100:
T->ImageWidth = (ptr->ValueOffset >> 16);
break;
case 0x0101:
T->ImageLength = (ptr->ValueOffset >> 16);
break;
case 0x0102:
T->BitsPerSample = (ptr->ValueOffset >> 16);
break;
case 0x0103:
T->Compression = (ptr->ValueOffset >> 16);
break;
case 0x0106:
T->PhotoInterp = (ptr->ValueOffset >> 16);
break;
case 0x0107:
T->Threshold = (ptr->ValueOffset >> 16);
break;
case 0x0108:
T->CellWidth = (ptr->ValueOffset >> 16);
break;
case 0x0109:
T->CellLength = (ptr->ValueOffset >> 16);
break;
case 0x010A:
T->FillOrder = (ptr->ValueOffset >> 16);
break;
case 0x010D:
fprintf(stderr,"Unsupported feature\n");
/*
lseek(fd,(long)ptr->ValueOffset,0);
*/
break;
case 0x010E:
fprintf(stderr,"Unsupported feature\n");
/*
lseek(fd,(long)ptr->ValueOffset,0);
*/
break;
case 0x010F:
/*
lseek(fd,(long)ptr->ValueOffset,0);
*/
fprintf(stderr,"Make: %s\n", T->Make);
break;
case 0x0110:
fprintf(stderr,"Unsupported feature\n");
/*
lseek(fd,(long)ptr->ValueOffset,0);
*/
break;
case 0x0111:
T->StOffsetCnt = ptr->Length;
if ((T->StripOffset = (LONG *) calloc(T->StOffsetCnt,
sizeof (LONG)))== NULL)
{
perror("calloc Soffset ");
return(FALSE);
}
if(T->StOffsetCnt == 1)
*(T->StripOffset) = ptr->ValueOffset;
else
{
lseek(fd, (long) ptr->ValueOffset, 0);
read(fd, T->StripOffset, T->StOffsetCnt * sizeof(LONG));
}
break;
case 0x0112:
T->Orientation= (ptr->ValueOffset >> 16);
break;
case 0x0115:
T->SamplesPixel= (ptr->ValueOffset >> 16);
break;
case 0x0116:
T->RowsStrip= (ptr->ValueOffset);
break;
case 0x0117:
T->StripByteCnt = (ptr->Length);
if ((T->SBytesCntOffset = (LONG *) calloc(T->StripByteCnt,
sizeof (LONG)))== NULL)
{
perror("calloc StripByteCnt ");
return(FALSE);
}
if(T->StripByteCnt == 1)
*(T->SBytesCntOffset) = ptr->ValueOffset;
else
{
lseek(fd,(long)ptr->ValueOffset,0);
read(fd,T->SBytesCntOffset,T->StripByteCnt*sizeof(LONG));
}
break;
case 0x0118:
T->MinSampleValue= (ptr->ValueOffset >> 16);
break;
case 0x0119:
T->MaxSampleValue= (ptr->ValueOffset >> 16);
break;
case 0x011A:
lseek(fd,(long)ptr->ValueOffset,0);
read(fd,TempRational,sizeof(TempRational));
T->Xres = TempRational[0]/TempRational[1];
break;
case 0x011B:
lseek(fd,(long)ptr->ValueOffset,0);
read(fd,TempRational,sizeof(TempRational));
T->Yres = TempRational[0]/TempRational[1];
break;
case 0x011C:
T->PlanarConfig= (ptr->ValueOffset >> 16);
break;
case 0x011D:
fprintf(stderr,"Unsupported feature: PageName\n");
/* T->PageName */
break;
case 0x011E:
fprintf(stderr,"Unsupported feature: Xpos\n");
/* T->XPos */
break;
case 0x011F:
fprintf(stderr,"Unsupported feature: Ypos\n");
/* T->YPos */
break;
case 0x0120:
fprintf(stderr,"Unsupported feature: FreeOffsets\n");
/* T->FreeOffsets */
break;
case 0x0121:
fprintf(stderr,"Unsupported feature: FreeByteCount \n");
/* T->FreeByteCount */
break;
case 0x0122:
fprintf(stderr,"Unsupported feature: GrayResUnit\n");
/* T->GrayResUnit */
break;
case 0x0123:
fprintf(stderr,"Unsupported feature: GrayResCurve\n");
/* T->GrayResCurve */
break;
case 0x0124:
fprintf(stderr,"Unsupported feature: Group3Option\n");
/* T->Group3Option */
break;
case 0x0125:
fprintf(stderr,"Unsupported feature: Group4Option\n");
/* T->Group4Option */
break;
case 0x0128:
fprintf(stderr,"Unsupported feature: ResolutionUnit\n");
/* T->ResolutionUnit */
break;
case 0x0129:
fprintf(stderr,"Unsupported feature: PageNumber\n");
/* T->PageNumber */
break;
case 0x012C:
fprintf(stderr,"Unsupported feature: ColorResUnit\n");
/* T->ColorResUnit */
break;
case 0x012D:
fprintf(stderr,"Unsupported feature: ColorResCurv\n");
/* T->ColorResCurv */
break;
default:
fprintf(stderr,"Unsupported feature: Unknown Tag\n");
fprintf(stderr,"Default\n");
break;
}
ptr++;
}
return(TRUE);
}
/*
** Dump header information
*/
dumpHeader(T,H)
struct Tiffstruct *T;
struct TiffHeader *H;
{
int i;
LONG *offptr;
fprintf(stderr,"Version: %d\n",H->Version);
fprintf(stderr,"ByteOrder: %c%c\n",
H->ByteOrder[0],
H->ByteOrder[1]);
fprintf(stderr,"Subfile Type: %d\n", T->SubFileType);
fprintf(stderr,"ImageWidth: %d\n", T->ImageWidth);
fprintf(stderr,"ImageLength: %d\n", T->ImageLength);
fprintf(stderr,"BitsPerSample: %d\n", T->BitsPerSample);
fprintf(stderr,"Compression: %d\n", T->Compression);
fprintf(stderr,"PhotoInterp: %d\n", T->PhotoInterp);
fprintf(stderr,"Threshold: %d\n", T->Threshold);
fprintf(stderr,"CellWidth: %d\n", T->CellWidth);
fprintf(stderr,"CellLength: %d\n", T->CellLength);
fprintf(stderr,"FillOrder: %d\n", T->FillOrder);
fprintf(stderr,"DocName: %s\n", T->DocName);
fprintf(stderr,"ImageDescript: %s\n", T->ImageDescript);
fprintf(stderr,"Model: %s\n", T->Model);
fprintf(stderr,"StripOffsetCnt: %d\n", T->StOffsetCnt);
offptr = T->StripOffset;
for(i=0; i < T->StOffsetCnt; i++)
{
fprintf(stderr,"Strip [%02d] starts at: %d \n", i,*offptr);
offptr++;
}
fprintf(stderr,"Orientation: %d\n", T->Orientation);
fprintf(stderr,"SamplesPixel: %d\n", T->SamplesPixel);
fprintf(stderr,"RowsStrip: %d\n", T->RowsStrip);
fprintf(stderr,"StripByteCnt: %d\n", T->StripByteCnt);
offptr = T->SBytesCntOffset;
for(i=0; i < T->StripByteCnt; i++)
{
fprintf(stderr,"Strip [%02d]: %d bytes\n", i,*offptr);
offptr++;
}
fprintf(stderr,"MinSampleValue: %d\n", T->MinSampleValue);
fprintf(stderr,"MaxSampleValue: %d\n", T->MaxSampleValue);
fprintf(stderr,"Xres: %d\n", T->Xres);
fprintf(stderr,"Yres: %d\n", T->Yres);
fprintf(stderr,"PlanarConfig: %d\n", T->PlanarConfig);
}