|
roentgen |
b75cab |
#include "StdAfx.h"
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
//#define STRICT
|
|
roentgen |
b75cab |
#include <windows.h></windows.h>
|
|
roentgen |
b75cab |
#include <windowsx.h></windowsx.h>
|
|
roentgen |
b75cab |
#include <commdlg.h></commdlg.h>
|
|
roentgen |
b75cab |
#include <stdlib.h> // MAX_ constants</stdlib.h>
|
|
roentgen |
b75cab |
#include "diblib.h"
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*--------------------------------------------------------------------
|
|
roentgen |
b75cab |
READ TIFF
|
|
roentgen |
b75cab |
Load the TIFF data from the file into memory. Return
|
|
roentgen |
b75cab |
a pointer to a valid DIB (or NULL for errors).
|
|
roentgen |
b75cab |
Uses the TIFFRGBA interface to libtiff.lib to convert
|
|
roentgen |
b75cab |
most file formats to a useable form. We just keep the 32 bit
|
|
roentgen |
b75cab |
form of the data to display, rather than optimizing for the
|
|
roentgen |
b75cab |
display.
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
Main entry points:
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
int ChkTIFF ( LPCTSTR lpszPath )
|
|
roentgen |
b75cab |
PVOID ReadTIFF ( LPCTSTR lpszPath )
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
RETURN
|
|
roentgen |
b75cab |
A valid DIB pointer for success; NULL for failure.
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
--------------------------------------------------------------------*/
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
#include "TiffLib/tiff.h"
|
|
roentgen |
b75cab |
#include "TiffLib/tiffio.h"
|
|
roentgen |
b75cab |
#include <assert.h></assert.h>
|
|
roentgen |
b75cab |
#include <stdio.h></stdio.h>
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// piggyback some data on top of the RGBA Image
|
|
roentgen |
b75cab |
struct TIFFDibImage {
|
|
roentgen |
b75cab |
TIFFRGBAImage tif;
|
|
roentgen |
b75cab |
int dibinstalled;
|
|
roentgen |
b75cab |
} ;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
HANDLE LoadTIFFinDIB(LPCTSTR lpFileName);
|
|
roentgen |
b75cab |
HANDLE TIFFRGBA2DIB(TIFFDibImage* dib, uint32* raster) ;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static void
|
|
roentgen |
b75cab |
MyWarningHandler(const char* module, const char* fmt, va_list ap)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
// ignore all warnings (unused tags, etc)
|
|
roentgen |
b75cab |
return;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static void
|
|
roentgen |
b75cab |
MyErrorHandler(const char* module, const char* fmt, va_list ap)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
return;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// Turn off the error and warning handlers to check if a valid file.
|
|
roentgen |
b75cab |
// Necessary because of the way that the Doc loads images and restart files.
|
|
roentgen |
b75cab |
int ChkTIFF ( LPCTSTR lpszPath )
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
int rtn = 0;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
TIFFErrorHandler eh;
|
|
roentgen |
b75cab |
TIFFErrorHandler wh;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
eh = TIFFSetErrorHandler(NULL);
|
|
roentgen |
b75cab |
wh = TIFFSetWarningHandler(NULL);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
TIFF* tif = TIFFOpen(lpszPath, "r");
|
|
roentgen |
b75cab |
if (tif) {
|
|
roentgen |
b75cab |
rtn = 1;
|
|
roentgen |
b75cab |
TIFFClose(tif);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
TIFFSetErrorHandler(eh);
|
|
roentgen |
b75cab |
TIFFSetWarningHandler(wh);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
return rtn;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
void DibInstallHack(TIFFDibImage* img) ;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
PVOID ReadTIFF ( LPCTSTR lpszPath )
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
void* pDIB = 0;
|
|
roentgen |
b75cab |
TIFFErrorHandler wh;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
wh = TIFFSetWarningHandler(MyWarningHandler);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
if (ChkTIFF(lpszPath)) {
|
|
roentgen |
b75cab |
TIFF* tif = TIFFOpen(lpszPath, "r");
|
|
roentgen |
b75cab |
if (tif) {
|
|
roentgen |
b75cab |
char emsg[1024];
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
if (TIFFRGBAImageOK(tif, emsg)) {
|
|
roentgen |
b75cab |
TIFFDibImage img;
|
|
roentgen |
b75cab |
char emsg[1024];
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
if (TIFFRGBAImageBegin(&img.tif, tif, -1, emsg)) {
|
|
roentgen |
b75cab |
size_t npixels;
|
|
roentgen |
b75cab |
uint32* raster;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
DibInstallHack(&img);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
npixels = img.tif.width * img.tif.height;
|
|
roentgen |
b75cab |
raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));
|
|
roentgen |
b75cab |
if (raster != NULL) {
|
|
roentgen |
b75cab |
if (TIFFRGBAImageGet(&img.tif, raster, img.tif.width, img.tif.height)) {
|
|
roentgen |
b75cab |
pDIB = TIFFRGBA2DIB(&img, raster);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
_TIFFfree(raster);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
TIFFRGBAImageEnd(&img.tif);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
else {
|
|
roentgen |
b75cab |
TRACE("Unable to open image(%s): %s\n", lpszPath, emsg );
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
TIFFClose(tif);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
TIFFSetWarningHandler(wh);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
return pDIB;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
HANDLE TIFFRGBA2DIB(TIFFDibImage* dib, uint32* raster)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
void* pDIB = 0;
|
|
roentgen |
b75cab |
TIFFRGBAImage* img = &dib->tif;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
uint32 imageLength;
|
|
roentgen |
b75cab |
uint32 imageWidth;
|
|
roentgen |
b75cab |
uint16 BitsPerSample;
|
|
roentgen |
b75cab |
uint16 SamplePerPixel;
|
|
roentgen |
b75cab |
uint32 RowsPerStrip;
|
|
roentgen |
b75cab |
uint16 PhotometricInterpretation;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
BITMAPINFOHEADER bi;
|
|
roentgen |
b75cab |
int dwDIBSize ;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
TIFFGetField(img->tif, TIFFTAG_IMAGEWIDTH, &imageWidth);
|
|
roentgen |
b75cab |
TIFFGetField(img->tif, TIFFTAG_IMAGELENGTH, &imageLength);
|
|
roentgen |
b75cab |
TIFFGetField(img->tif, TIFFTAG_BITSPERSAMPLE, &BitsPerSample);
|
|
roentgen |
b75cab |
TIFFGetField(img->tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip);
|
|
roentgen |
b75cab |
TIFFGetField(img->tif, TIFFTAG_SAMPLESPERPIXEL, &SamplePerPixel);
|
|
roentgen |
b75cab |
TIFFGetField(img->tif, TIFFTAG_PHOTOMETRIC, &PhotometricInterpretation);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
if ( BitsPerSample == 1 && SamplePerPixel == 1 && dib->dibinstalled ) { // bilevel
|
|
roentgen |
b75cab |
bi.biSize = sizeof(BITMAPINFOHEADER);
|
|
roentgen |
b75cab |
bi.biWidth = imageWidth;
|
|
roentgen |
b75cab |
bi.biHeight = imageLength;
|
|
roentgen |
b75cab |
bi.biPlanes = 1; // always
|
|
roentgen |
b75cab |
bi.biBitCount = 1;
|
|
roentgen |
b75cab |
bi.biCompression = BI_RGB;
|
|
roentgen |
b75cab |
bi.biSizeImage = WIDTHBYTES(bi.biWidth * bi.biBitCount) * bi.biHeight;
|
|
roentgen |
b75cab |
bi.biXPelsPerMeter = 0;
|
|
roentgen |
b75cab |
bi.biYPelsPerMeter = 0;
|
|
roentgen |
b75cab |
bi.biClrUsed = 0; // must be zero for RGB compression (none)
|
|
roentgen |
b75cab |
bi.biClrImportant = 0; // always
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// Get the size of the DIB
|
|
roentgen |
b75cab |
dwDIBSize = GetDIBSize( &bi );
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// Allocate for the BITMAPINFO structure and the color table.
|
|
roentgen |
b75cab |
pDIB = GlobalAllocPtr( GHND, dwDIBSize );
|
|
roentgen |
b75cab |
if (pDIB == 0) {
|
|
roentgen |
b75cab |
return( NULL );
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// Copy the header info
|
|
roentgen |
b75cab |
*((BITMAPINFOHEADER*)pDIB) = bi;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// Get a pointer to the color table
|
|
roentgen |
b75cab |
RGBQUAD *pRgbq = (RGBQUAD *)((LPSTR)pDIB + sizeof(BITMAPINFOHEADER));
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
pRgbq[0].rgbRed = 0;
|
|
roentgen |
b75cab |
pRgbq[0].rgbBlue = 0;
|
|
roentgen |
b75cab |
pRgbq[0].rgbGreen = 0;
|
|
roentgen |
b75cab |
pRgbq[0].rgbReserved = 0;
|
|
roentgen |
b75cab |
pRgbq[1].rgbRed = 255;
|
|
roentgen |
b75cab |
pRgbq[1].rgbBlue = 255;
|
|
roentgen |
b75cab |
pRgbq[1].rgbGreen = 255;
|
|
roentgen |
b75cab |
pRgbq[1].rgbReserved = 255;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// Pointers to the bits
|
|
roentgen |
b75cab |
//PVOID pbiBits = (LPSTR)pRgbq + bi.biClrUsed * sizeof(RGBQUAD);
|
|
roentgen |
b75cab |
//
|
|
roentgen |
b75cab |
// In the BITMAPINFOHEADER documentation, it appears that
|
|
roentgen |
b75cab |
// there should be no color table for 32 bit images, but
|
|
roentgen |
b75cab |
// experience shows that the image is off by 3 words if it
|
|
roentgen |
b75cab |
// is not included. So here it is.
|
|
roentgen |
b75cab |
PVOID pbiBits = GetDIBImagePtr((BITMAPINFOHEADER*)pDIB); //(LPSTR)pRgbq + 3 * sizeof(RGBQUAD);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
int sizeWords = bi.biSizeImage/4;
|
|
roentgen |
b75cab |
RGBQUAD* rgbDib = (RGBQUAD*)pbiBits;
|
|
roentgen |
b75cab |
long* rgbTif = (long*)raster;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
_TIFFmemcpy(pbiBits, raster, bi.biSizeImage);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// For now just always default to the RGB 32 bit form. // save as 32 bit for simplicity
|
|
roentgen |
b75cab |
else if ( true /*BitsPerSample == 8 && SamplePerPixel == 3*/ ) { // 24 bit color
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
bi.biSize = sizeof(BITMAPINFOHEADER);
|
|
roentgen |
b75cab |
bi.biWidth = imageWidth;
|
|
roentgen |
b75cab |
bi.biHeight = imageLength;
|
|
roentgen |
b75cab |
bi.biPlanes = 1; // always
|
|
roentgen |
b75cab |
bi.biBitCount = 32;
|
|
roentgen |
b75cab |
bi.biCompression = BI_RGB;
|
|
roentgen |
b75cab |
bi.biSizeImage = WIDTHBYTES(bi.biWidth * bi.biBitCount) * bi.biHeight;
|
|
roentgen |
b75cab |
bi.biXPelsPerMeter = 0;
|
|
roentgen |
b75cab |
bi.biYPelsPerMeter = 0;
|
|
roentgen |
b75cab |
bi.biClrUsed = 0; // must be zero for RGB compression (none)
|
|
roentgen |
b75cab |
bi.biClrImportant = 0; // always
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// Get the size of the DIB
|
|
roentgen |
b75cab |
dwDIBSize = GetDIBSize( &bi );
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// Allocate for the BITMAPINFO structure and the color table.
|
|
roentgen |
b75cab |
pDIB = GlobalAllocPtr( GHND, dwDIBSize );
|
|
roentgen |
b75cab |
if (pDIB == 0) {
|
|
roentgen |
b75cab |
return( NULL );
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// Copy the header info
|
|
roentgen |
b75cab |
*((BITMAPINFOHEADER*)pDIB) = bi;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// Get a pointer to the color table
|
|
roentgen |
b75cab |
RGBQUAD *pRgbq = (RGBQUAD *)((LPSTR)pDIB + sizeof(BITMAPINFOHEADER));
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// Pointers to the bits
|
|
roentgen |
b75cab |
//PVOID pbiBits = (LPSTR)pRgbq + bi.biClrUsed * sizeof(RGBQUAD);
|
|
roentgen |
b75cab |
//
|
|
roentgen |
b75cab |
// In the BITMAPINFOHEADER documentation, it appears that
|
|
roentgen |
b75cab |
// there should be no color table for 32 bit images, but
|
|
roentgen |
b75cab |
// experience shows that the image is off by 3 words if it
|
|
roentgen |
b75cab |
// is not included. So here it is.
|
|
roentgen |
b75cab |
PVOID pbiBits = (LPSTR)pRgbq + 3 * sizeof(RGBQUAD);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
int sizeWords = bi.biSizeImage/4;
|
|
roentgen |
b75cab |
RGBQUAD* rgbDib = (RGBQUAD*)pbiBits;
|
|
roentgen |
b75cab |
long* rgbTif = (long*)raster;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// Swap the byte order while copying
|
|
roentgen |
b75cab |
for ( int i = 0 ; i < sizeWords ; ++i )
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
rgbDib[i].rgbRed = TIFFGetR(rgbTif[i]);
|
|
roentgen |
b75cab |
rgbDib[i].rgbBlue = TIFFGetB(rgbTif[i]);
|
|
roentgen |
b75cab |
rgbDib[i].rgbGreen = TIFFGetG(rgbTif[i]);
|
|
roentgen |
b75cab |
rgbDib[i].rgbReserved = 0;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
return pDIB;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
///////////////////////////////////////////////////////////////
|
|
roentgen |
b75cab |
//
|
|
roentgen |
b75cab |
// Hacked from tif_getimage.c in libtiff in v3.5.7
|
|
roentgen |
b75cab |
//
|
|
roentgen |
b75cab |
//
|
|
roentgen |
b75cab |
typedef unsigned char u_char;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
#define DECLAREContigPutFunc(name) \
|
|
roentgen |
b75cab |
static void name(\
|
|
roentgen |
b75cab |
TIFFRGBAImage* img, \
|
|
roentgen |
b75cab |
uint32* cp, \
|
|
roentgen |
b75cab |
uint32 x, uint32 y, \
|
|
roentgen |
b75cab |
uint32 w, uint32 h, \
|
|
roentgen |
b75cab |
int32 fromskew, int32 toskew, \
|
|
roentgen |
b75cab |
u_char* pp \
|
|
roentgen |
b75cab |
)
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
#define DECLARESepPutFunc(name) \
|
|
roentgen |
b75cab |
static void name(\
|
|
roentgen |
b75cab |
TIFFRGBAImage* img,\
|
|
roentgen |
b75cab |
uint32* cp,\
|
|
roentgen |
b75cab |
uint32 x, uint32 y, \
|
|
roentgen |
b75cab |
uint32 w, uint32 h,\
|
|
roentgen |
b75cab |
int32 fromskew, int32 toskew,\
|
|
roentgen |
b75cab |
u_char* r, u_char* g, u_char* b, u_char* a\
|
|
roentgen |
b75cab |
)
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
DECLAREContigPutFunc(putContig1bitTile);
|
|
roentgen |
b75cab |
static int getStripContig1Bit(TIFFRGBAImage* img, uint32* uraster, uint32 w, uint32 h);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
//typdef struct TIFFDibImage {
|
|
roentgen |
b75cab |
// TIFFRGBAImage tif;
|
|
roentgen |
b75cab |
// dibinstalled;
|
|
roentgen |
b75cab |
//} TIFFDibImage ;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
void DibInstallHack(TIFFDibImage* dib) {
|
|
roentgen |
b75cab |
TIFFRGBAImage* img = &dib->tif;
|
|
roentgen |
b75cab |
dib->dibinstalled = false;
|
|
roentgen |
b75cab |
switch (img->photometric) {
|
|
roentgen |
b75cab |
case PHOTOMETRIC_MINISWHITE:
|
|
roentgen |
b75cab |
case PHOTOMETRIC_MINISBLACK:
|
|
roentgen |
b75cab |
switch (img->bitspersample) {
|
|
roentgen |
b75cab |
case 1:
|
|
roentgen |
b75cab |
img->put.contig = putContig1bitTile;
|
|
roentgen |
b75cab |
img->get = getStripContig1Bit;
|
|
roentgen |
b75cab |
dib->dibinstalled = true;
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* 1-bit packed samples => 1-bit
|
|
roentgen |
b75cab |
*
|
|
roentgen |
b75cab |
* Override to just copy the data
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
DECLAREContigPutFunc(putContig1bitTile)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
int samplesperpixel = img->samplesperpixel;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
(void) y;
|
|
roentgen |
b75cab |
fromskew *= samplesperpixel;
|
|
roentgen |
b75cab |
int wb = WIDTHBYTES(w);
|
|
roentgen |
b75cab |
u_char* ucp = (u_char*)cp;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/* Conver 'w' to bytes from pixels (rounded up) */
|
|
roentgen |
b75cab |
w = (w+7)/8;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
while (h-- > 0) {
|
|
roentgen |
b75cab |
_TIFFmemcpy(ucp, pp, w);
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
for (x = wb; x-- > 0;) {
|
|
roentgen |
b75cab |
*cp++ = rgbi(Map[pp[0]], Map[pp[1]], Map[pp[2]]);
|
|
roentgen |
b75cab |
pp += samplesperpixel;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
ucp += (wb + toskew);
|
|
roentgen |
b75cab |
pp += (w + fromskew);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Hacked from the tif_getimage.c file.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
static uint32
|
|
roentgen |
b75cab |
setorientation(TIFFRGBAImage* img, uint32 h)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
TIFF* tif = img->tif;
|
|
roentgen |
b75cab |
uint32 y;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
switch (img->orientation) {
|
|
roentgen |
b75cab |
case ORIENTATION_BOTRIGHT:
|
|
roentgen |
b75cab |
case ORIENTATION_RIGHTBOT: /* XXX */
|
|
roentgen |
b75cab |
case ORIENTATION_LEFTBOT: /* XXX */
|
|
roentgen |
b75cab |
TIFFWarning(TIFFFileName(tif), "using bottom-left orientation");
|
|
roentgen |
b75cab |
img->orientation = ORIENTATION_BOTLEFT;
|
|
roentgen |
b75cab |
/* fall thru... */
|
|
roentgen |
b75cab |
case ORIENTATION_BOTLEFT:
|
|
roentgen |
b75cab |
y = 0;
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case ORIENTATION_TOPRIGHT:
|
|
roentgen |
b75cab |
case ORIENTATION_RIGHTTOP: /* XXX */
|
|
roentgen |
b75cab |
case ORIENTATION_LEFTTOP: /* XXX */
|
|
roentgen |
b75cab |
default:
|
|
roentgen |
b75cab |
TIFFWarning(TIFFFileName(tif), "using top-left orientation");
|
|
roentgen |
b75cab |
img->orientation = ORIENTATION_TOPLEFT;
|
|
roentgen |
b75cab |
/* fall thru... */
|
|
roentgen |
b75cab |
case ORIENTATION_TOPLEFT:
|
|
roentgen |
b75cab |
y = h-1;
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
return (y);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Get a strip-organized image that has
|
|
roentgen |
b75cab |
* PlanarConfiguration contiguous if SamplesPerPixel > 1
|
|
roentgen |
b75cab |
* or
|
|
roentgen |
b75cab |
* SamplesPerPixel == 1
|
|
roentgen |
b75cab |
*
|
|
roentgen |
b75cab |
* Hacked from the tif_getimage.c file.
|
|
roentgen |
b75cab |
*
|
|
roentgen |
b75cab |
* This is set up to allow us to just copy the data to the raster
|
|
roentgen |
b75cab |
* for 1-bit bitmaps
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
static int
|
|
roentgen |
b75cab |
getStripContig1Bit(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
TIFF* tif = img->tif;
|
|
roentgen |
b75cab |
tileContigRoutine put = img->put.contig;
|
|
roentgen |
b75cab |
uint16 orientation;
|
|
roentgen |
b75cab |
uint32 row, y, nrow, rowstoread;
|
|
roentgen |
b75cab |
uint32 pos;
|
|
roentgen |
b75cab |
u_char* buf;
|
|
roentgen |
b75cab |
uint32 rowsperstrip;
|
|
roentgen |
b75cab |
uint32 imagewidth = img->width;
|
|
roentgen |
b75cab |
tsize_t scanline;
|
|
roentgen |
b75cab |
int32 fromskew, toskew;
|
|
roentgen |
b75cab |
tstrip_t strip;
|
|
roentgen |
b75cab |
tsize_t stripsize;
|
|
roentgen |
b75cab |
u_char* braster = (u_char*)raster; // byte wide raster
|
|
roentgen |
b75cab |
uint32 wb = WIDTHBYTES(w);
|
|
roentgen |
b75cab |
int ret = 1;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
buf = (u_char*) _TIFFmalloc(TIFFStripSize(tif));
|
|
roentgen |
b75cab |
if (buf == 0) {
|
|
roentgen |
b75cab |
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer");
|
|
roentgen |
b75cab |
return (0);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
y = setorientation(img, h);
|
|
roentgen |
b75cab |
orientation = img->orientation;
|
|
roentgen |
b75cab |
toskew = -(int32) (orientation == ORIENTATION_TOPLEFT ? wb+wb : wb-wb);
|
|
roentgen |
b75cab |
TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
|
|
roentgen |
b75cab |
scanline = TIFFScanlineSize(tif);
|
|
roentgen |
b75cab |
fromskew = (w < imagewidth ? imagewidth - w : 0)/8;
|
|
roentgen |
b75cab |
for (row = 0; row < h; row += nrow)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
|
|
roentgen |
b75cab |
nrow = (row + rowstoread > h ? h - row : rowstoread);
|
|
roentgen |
b75cab |
strip = TIFFComputeStrip(tif,row+img->row_offset, 0);
|
|
roentgen |
b75cab |
stripsize = ((row + img->row_offset)%rowsperstrip + nrow) * scanline;
|
|
roentgen |
b75cab |
if (TIFFReadEncodedStrip(tif, strip, buf, stripsize ) < 0
|
|
roentgen |
b75cab |
&& img->stoponerr)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
ret = 0;
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
pos = ((row + img->row_offset) % rowsperstrip) * scanline;
|
|
roentgen |
b75cab |
(*put)(img, (uint32*)(braster+y*wb), 0, y, w, nrow, fromskew, toskew, buf + pos);
|
|
roentgen |
b75cab |
y += (orientation == ORIENTATION_TOPLEFT ?-(int32) nrow : (int32) nrow);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
_TIFFfree(buf);
|
|
roentgen |
b75cab |
return (ret);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Local Variables:
|
|
roentgen |
b75cab |
* mode: c++
|
|
roentgen |
b75cab |
* c-basic-offset: 8
|
|
roentgen |
b75cab |
* fill-column: 78
|
|
roentgen |
b75cab |
* End:
|
|
roentgen |
b75cab |
*/
|