home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright 1990 by John Wiley & Sons, Inc.
- All Rights Reserved.
- */
- /****************************************/
- /* TIFF Function Library */
- /* written in Turbo C 2.0 */
- /* by */
- /* Craig A. Lindley */
- /* */
- /* Vers: 1.0 Last Update: 12/29/89 */
- /****************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <process.h>
- #include <mem.h>
- #include <conio.h>
- #include <string.h>
- #include <graphics.h>
- #include "misc.h"
- #include "vga.h"
- #include "pcx.h"
- #include "tiffintf.h"
-
-
- /*
- Create a TIFF file from the image currently
- being displayed on the VGA adapter.
- */
-
- CompletionCode WriteTIFFFile(char *FileName,
- unsigned BitsPerSample,
- unsigned SamplesPerPixel,
- unsigned ImageWidth, unsigned ImageLength)
- {
- TIFF *tif;
- char *RowBuffer = NULL;
- char *Message = "";
- register unsigned Col, Row;
- unsigned *RedColorMap = NULL;
- unsigned *GreenColorMap = NULL;
- unsigned *BlueColorMap = NULL;
- unsigned Index, ColorReg, BytesPerRow, Sample;
- unsigned RedColor, GreenColor, BlueColor;
- unsigned BitPlane, Mask;
- long RowsPerStrip;
- struct palettetype Palette;
-
- /*
- Allocate colormaps arrays. Calloc clears them to zero.
- */
- if((RedColorMap = (unsigned *) calloc(MAX256PALETTECOLORS,sizeof(unsigned))) == NULL)
- {
- Message = "No memory for RedColorMap";
- goto NoMem;
- }
-
- if((GreenColorMap = (unsigned *) calloc(MAX256PALETTECOLORS,sizeof(unsigned))) == NULL)
- {
- Message = "No memory for GreenColorMap";
- goto NoMem;
- }
-
- if((BlueColorMap = (unsigned *) calloc(MAX256PALETTECOLORS,sizeof(unsigned))) == NULL)
- {
- Message = "No memory for BlueColorMap";
- goto NoMem;
- }
-
- tif = TIFFOpen(FileName,"w");
- if (!tif)
- {
- restorecrtmode();
- printf("Error opening output file: %s\n",FileName);
- return(EFileIOError);
- }
-
- /* set constant tags */
- TIFFSetField(tif,TIFFTAG_SUBFILETYPE,0L);
- TIFFSetField(tif,TIFFTAG_IMAGEWIDTH,(long)ImageWidth);
- TIFFSetField(tif,TIFFTAG_IMAGELENGTH,(long)ImageLength);
- TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE,BitsPerSample);
- TIFFSetField(tif,TIFFTAG_COMPRESSION,COMPRESSION_LZW);
- TIFFSetField(tif,TIFFTAG_PHOTOMETRIC,PHOTOMETRIC_PALETTE);
- TIFFSetField(tif,TIFFTAG_MAKE,"Craig's Video Digitizer");
- TIFFSetField(tif,TIFFTAG_ARTIST,"Craig A. Lindley");
- TIFFSetField(tif,TIFFTAG_HOSTCOMPUTER,"IBM PC with VGA graphics adapter");
- TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,SamplesPerPixel);
- TIFFSetField(tif,TIFFTAG_XRESOLUTION,72.0);
- TIFFSetField(tif,TIFFTAG_YRESOLUTION,72.0);
- if (SamplesPerPixel == 1)
- TIFFSetField(tif,TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG);
- else
- TIFFSetField(tif,TIFFTAG_PLANARCONFIG,PLANARCONFIG_SEPARATE);
-
- TIFFSetField(tif,TIFFTAG_RESOLUTIONUNIT,RESUNIT_INCH);
-
- BytesPerRow = (unsigned) TIFFScanlineSize(tif);
- /* allocate memory for single scan line from display */
- if ((RowBuffer = malloc(BytesPerRow)) == NULL)
- {
- Message = "No memory for RowBuffer";
- goto NoMem;
- }
- /* make strips approximately 8K in length */
- RowsPerStrip = 8; /* (8L*1024L)/(long) BytesPerRow; */
-
- TIFFSetField(tif,TIFFTAG_ROWSPERSTRIP,RowsPerStrip);
-
- if ((BitsPerSample == 1) || (BitsPerSample == 4))
- {
- /* read palette from VGA adapter */
- getpalette(&Palette);
- for (Index=0; Index < 16; Index++)
- {
- /*
- Even 16 color 320x200 images use VGA mode 13H
- without a palette.
- */
- if (ImageWidth == LRMAXCOLS)
- ColorReg = Index;
- else
- ColorReg = Palette.colors[Index];
- /* read color register components from VGA */
- GetAColorReg(ColorReg,&RedColor,&GreenColor,&BlueColor);
- /*
- Scale color components to range 0..255 as
- required by the TIFF spec. Normal range is
- from 0..63.
- */
- RedColorMap[Index] = RedColor<<2;
- GreenColorMap[Index] = GreenColor<<2;
- BlueColorMap[Index] = BlueColor<<2;
- }
- }
- else
- {
- for (Index=0; Index < MAX256PALETTECOLORS; Index++)
- {
- /* read color register components from VGA */
- GetAColorReg(Index,&RedColor,&GreenColor,&BlueColor);
- /*
- Scale color components to range 0..255 as
- required by the TIFF spec. Normal range is
- from 0..63.
- */
- RedColorMap[Index] = RedColor<<2;
- GreenColorMap[Index] = GreenColor<<2;
- BlueColorMap[Index] = BlueColor<<2;
- }
- }
-
- TIFFSetField(tif,TIFFTAG_COLORMAP,RedColorMap,GreenColorMap,BlueColorMap);
-
- if (ImageWidth == HRMAXCOLS) /* a 640x200 or 640x480 image */
- {
- if (SamplesPerPixel == 1)
- {
- for (Row = 0; Row < ImageLength; Row++)
- {
- for (Col=0; Col < HRMAXCOLS; Col+=2)
- {
- Sample = getpixel(Col,Row) << 4;
- RowBuffer[Col>>1] = Sample + getpixel(Col+1,Row);
- }
- if (!TIFFWriteScanline(tif,RowBuffer,Row,0))
- return(EWrtScanLine);
- }
- }
- else
- {
- /* Four samples per pixel */
- for (BitPlane = 0; BitPlane < SamplesPerPixel; BitPlane++)
- {
- Mask = 1 << BitPlane;
- for (Row = 0; Row < ImageLength; Row++)
- {
- memset(RowBuffer,0,BytesPerRow);
- for (Col=0; Col < HRMAXCOLS; Col++)
- if (getpixel(Col,Row) & Mask)
- RowBuffer[Col>>3] |= 1 << (7 - (Col % BITSPERBYTE));
- if (!TIFFWriteScanline(tif,RowBuffer,Row,BitPlane))
- return(EWrtScanLine);
- }
- }
- }
- }
- else
- /*
- 320x200 pixel image. All 320x200 images are assumed to use
- VGA mode 13H. For this reason, the GetPixel256() function
- must be used to read the pixels from the image currently
- displayed on the screen.
- */
- {
- if (BitsPerSample == 4)
- {
- for (Row = 0; Row < ImageLength; Row++)
- {
- for (Col=0; Col < LRMAXCOLS; Col+=2)
- {
- Sample = GetPixel256(Col,Row) << 4;
- RowBuffer[Col>>1] = Sample + GetPixel256(Col+1,Row);
- }
- if (!TIFFWriteScanline(tif,RowBuffer,Row,0))
- return(EWrtScanLine);
- }
- }
- else /* 320x200 8 bits/sample image */
- {
- for (Row = 0; Row < ImageLength; Row++)
- {
- for (Col=0; Col < LRMAXCOLS; Col++)
- RowBuffer[Col] = GetPixel256(Col,Row);
-
- if (!TIFFWriteScanline(tif,RowBuffer,Row,0))
- return(EWrtScanLine);
- }
- }
- }
- TIFFClose(tif);
- free((char *) RowBuffer);
- free((char *) RedColorMap);
- free((char *) GreenColorMap);
- free((char *) BlueColorMap);
- return(NoError);
-
- NoMem:
- restorecrtmode();
- printf("Error: %s\n",Message);
- if (RowBuffer)
- free((char *) RowBuffer);
- if (RedColorMap)
- free((char *) RedColorMap);
- if (GreenColorMap)
- free((char *) GreenColorMap);
- if (BlueColorMap)
- free((char *) BlueColorMap);
- TIFFClose(tif);
- return(ENoMemory);
- }
-
- /*
- This function will display a TIFF file on the VGA
- graphics adapter. It will complain about TIFF files
- it doesn't understand. This code only supports a small
- portion of possible TIFF images. Constraints mainly a
- result of VGA limitations.
- */
-
- CompletionCode DisplayTIFFFile(char *FileName, unsigned Verbose)
- {
- TIFF *tif;
- unsigned long ImageWidth, ImageLength;
- unsigned PhotometricIntrp, Index;
- unsigned *RedColorMap, *GreenColorMap, *BlueColorMap;
- register short PixelNum;
- register unsigned Col, Row;
- unsigned MaxColors, LoadColorMap, RowByte, RowByteCnt;
- unsigned BitColor, BitPlane, LowResImage;
- unsigned long ScanlineBytes;
- BYTE *RowBuffer;
- register BYTE *RowBufferPtr;
- char *Message = "";
- BYTE *Map = NULL;
- struct palettetype Palette;
-
- unsigned BitsPerSample = 1; /* install TIFF defaults */
- unsigned SamplesPerPixel = 1;
- unsigned PlanarConfig = PLANARCONFIG_CONTIG;
-
- /* Attemp to open the specified TIFF file */
- tif = TIFFOpen(FileName,"r");
- if (!tif)
- {
- restorecrtmode();
- printf("TIFF error: File %s not found or directory format error",FileName);
- return(EFileNotFound);
- }
-
- if (Verbose)
- {
- printf("\nTIFF file: %s\n\n",FileName);
- TIFFPrintDirectory(tif, stdout, TRUE, TRUE, TRUE);
- getch();
- }
- if ((RowBuffer = malloc((unsigned) TIFFScanlineSize(tif))) == NULL)
- {
- Message = "No memory for RowBuffer";
- goto bad;
- }
-
- /* check for the presence of the proper tag compliment */
- if (!TIFFGetField(tif,TIFFTAG_IMAGEWIDTH,&ImageWidth))
- {
- Message = "ImageWidth tag missing";
- goto bad;
- }
- ImageWidth = MIN(ImageWidth,HRMAXCOLS);
-
- if (!TIFFGetField(tif,TIFFTAG_IMAGELENGTH,&ImageLength))
- {
- Message = "ImageLength tag missing";
- goto bad;
- }
- ImageLength = MIN(ImageLength,HRMAXROWS);
-
- if (!TIFFGetField(tif,TIFFTAG_BITSPERSAMPLE,&BitsPerSample))
- printf("Warning BitsPerSample tag missing\n");
-
- /* check for proper values */
- if ((BitsPerSample != 1) && (BitsPerSample != 4) && (BitsPerSample != 8))
- {
- Message = "BitsPerSample not 1,4 or 8";
- goto bad;
- }
-
- if (!TIFFGetField(tif,TIFFTAG_SAMPLESPERPIXEL,&SamplesPerPixel))
- printf("Warning SamplesPerPixel tag missing\n");
- /* check for proper value */
-
- if ((SamplesPerPixel != 1) && (SamplesPerPixel != 4))
- {
- Message = "SamplesPerPixel not 1 or 4";
- goto bad;
- }
-
- if(!TIFFGetField(tif,TIFFTAG_PLANARCONFIG,&PlanarConfig))
- printf("Warning PlanarConfig tag missing\n");
-
-
- if (!TIFFGetField(tif,TIFFTAG_PHOTOMETRIC,&PhotometricIntrp))
- {
- Message = "PhotometricInterpretation tag missing";
- goto bad;
- }
- /* check for proper value */
- if ((PhotometricIntrp != PHOTOMETRIC_MINISWHITE) &&
- (PhotometricIntrp != PHOTOMETRIC_MINISBLACK) &&
- (PhotometricIntrp != PHOTOMETRIC_PALETTE))
- {
- Message = "Cannot handle this PhotometricInterpretation";
- goto bad;
- }
- /*
- Figure out the max number of colors necessary for this
- image. Create a mapping function, only required for
- black and white images, to convert images which have
- the color white as the minimum value to minimum black.
- as required by the VGA adapter. The variable LoadColorMap
- will be set true if this image contains a COLORMAP tag.
- It will cause the palette to be loaded later.
- */
- MaxColors = 1 << (BitsPerSample * SamplesPerPixel);
- Map = (char *)malloc((MaxColors) * sizeof (BYTE));
- LoadColorMap = FALSE;
- LowResImage = FALSE;
- switch(PhotometricIntrp)
- {
- case PHOTOMETRIC_MINISBLACK:
- for (Index=0; Index < MaxColors ; Index++)
- Map[Index] = Index;
- break;
- case PHOTOMETRIC_MINISWHITE:
- for (Index=0; Index < MaxColors; Index++)
- Map[Index] = MaxColors - Index - 1;
- break;
- case PHOTOMETRIC_PALETTE:
- /*
- Check to see if file has COLORMAP tag. If so, load
- the three pointers to the colormap data.
- */
- if (!TIFFGetField(tif,TIFFTAG_COLORMAP,&RedColorMap,
- &GreenColorMap,
- &BlueColorMap))
- {
- Message = "ColorMap tag missing";
- goto bad;
- }
- LoadColorMap = TRUE;
- break;
- default:
- Message = "Unsupported PhotometricInterpretation";
- goto bad;
- }
-
- InitGraphics();
-
- /* Determine VGA mode to use for display of image */
- if (ImageWidth <= LRMAXCOLS) /* less than 320 pixels */
- {
- ImageLength = MIN(ImageLength,LRMAXROWS); /* truncate to 200 */
- Set256ColorMode(); /* VGA mode 13H */
- LoadGray64Palette(); /* default 64 levels of gray */
- LowResImage = TRUE;
- }
- else
- {
- ImageWidth = MIN(ImageWidth,HRMAXCOLS); /* truncate to 640 pixels */
- if (ImageWidth <= LRMAXROWS) /* 640x200 image ? */
- setgraphmode(VGALO);
- else if (ImageWidth <= MRMAXROWS)/* 640x350 image ? */
- setgraphmode(VGAMED);
- else /* 640x480 image */
- setgraphmode(VGAHI);
-
- LoadGray16Palette(); /* 16 levels of gray palette */
- }
- if (LoadColorMap)
- {
- /*
- Load the color registers with this palette after
- scaling the color data by 4. Scaling is necessary
- because data ranges from 0..255 and VGA accepts
- 0..63.
- */
- if (!LowResImage)
- Palette.size = MaxColors;
- for (Index=0; Index < MaxColors; Index++)
- {
- if (!LowResImage)
- Palette.colors[Index] = Index;
- SetAColorReg(Index,RedColorMap[Index] >>2,
- GreenColorMap[Index]>>2,
- BlueColorMap[Index] >>2);
- }
- if (!LowResImage)
- setallpalette(&Palette);
- }
- switch(BitsPerSample)
- {
- case 1:
- if (SamplesPerPixel == 1)
- {
- ScanlineBytes =
- MIN(TIFFScanlineSize(tif),ImageWidth/(long)BITSPERBYTE);
- for (Row=0; Row < ImageLength; Row++)
- {
- if (!TIFFReadScanline(tif, RowBuffer, Row, 0))
- break;
- RowBufferPtr = RowBuffer;
- for (RowByteCnt=0; RowByteCnt < ScanlineBytes; RowByteCnt++)
- {
- RowByte = *RowBufferPtr++;
- for (PixelNum=7; PixelNum >= 0; PixelNum--)
- {
- BitColor = (Map[((RowByte & (1 << PixelNum)) != 0)])? 15:0;
- putpixel(RowByteCnt*8+(7-PixelNum),Row,BitColor);
- }
- }
- }
- }
- else /* Samples per Pixel = 4 */
- {
- for (Row=0; Row < ImageLength; Row++)
- {
- if (!TIFFReadScanline(tif, RowBuffer, Row, 0))
- break;
- for (Col = 0; Col < ImageWidth; Col++)
- if (LoadColorMap && (ImageWidth == LRMAXCOLS))
- PutPixel256(Col,Row,
- (RowBuffer[Col>>3] & (1 << (7 - Col % BITSPERBYTE)))? 1:0);
- else
- putpixel(Col,Row,
- (RowBuffer[Col>>3] & (1 << (7 - Col % BITSPERBYTE)))? 1:0);
-
- }
- for (BitPlane = 1; BitPlane < SamplesPerPixel; BitPlane++)
- for (Row=0; Row < ImageLength; Row++)
- {
- if (!TIFFReadScanline(tif, RowBuffer, Row, BitPlane))
- break;
- for (Col = 0; Col < ImageWidth; Col++)
- if (RowBuffer[Col>>3] & (1 << (7 - Col % BITSPERBYTE)))
- if (LoadColorMap && (ImageWidth == LRMAXCOLS))
- PutPixel256(Col,Row, GetPixel256(Col,Row) | (1 << BitPlane));
- else
- putpixel(Col,Row, getpixel(Col,Row) | (1 << BitPlane));
-
- }
- }
- break;
- case 4:
- ScanlineBytes = MIN(TIFFScanlineSize(tif),ImageWidth/2L);
- for (Row=0; Row < ImageLength; Row++)
- {
- if (!TIFFReadScanline(tif, RowBuffer, Row, 0))
- break;
- RowBufferPtr = RowBuffer;
- for (RowByteCnt=0; RowByteCnt < ScanlineBytes; RowByteCnt++)
- {
- RowByte = *RowBufferPtr++;
- if (LoadColorMap && (ImageWidth == LRMAXCOLS))
- {
- PutPixel256(RowByteCnt*2,Row,((RowByte>>4) & 0xFF));
- PutPixel256(RowByteCnt*2+1,Row,(RowByte & 0xFF));
- }
- else
- {
- putpixel(RowByteCnt*2,Row,((RowByte>>4) & 0xFF));
- putpixel(RowByteCnt*2+1,Row,(RowByte & 0xFF));
- }
- }
- }
- break;
- case 8:
- ScanlineBytes = MIN(TIFFScanlineSize(tif),ImageWidth);
- for (Row=0; Row < ImageLength; Row++)
- {
- if (!TIFFReadScanline(tif, RowBuffer, Row, 0))
- break;
- RowBufferPtr = RowBuffer;
- for (RowByteCnt=0; RowByteCnt < ScanlineBytes; RowByteCnt++)
- PutPixel256(RowByteCnt,Row,(unsigned) *RowBufferPtr++);
- }
- break;
- }
- if (Map)
- free((char *) Map);
- if (RowBuffer)
- free((char *) RowBuffer);
- TIFFClose(tif);
- return(TRUE);
-
- bad:
- restorecrtmode();
- printf("Error: %s\n",Message);
- if (Map)
- free((char *) Map);
- if (RowBuffer)
- free((char *) RowBuffer);
- TIFFClose(tif);
- return(FALSE);
- }
-
-