📄 dim_tiff_format_io.cpp
字号:
}
void write_line_segment(void *po, void *bufo, TDimImageBitmap *img, DIM_UINT sample, DIM_ULONG w)
{
if (img->i.depth == 8) write_line_segment_8 (po, bufo, img, sample, w);
if (img->i.depth == 16) write_line_segment_16 (po, bufo, img, sample, w);
}
//****************************************************************************
// SCANLINE METHOD TIFF
//****************************************************************************
int read_scanline_tiff(TIFF *tif, TDimImageBitmap *img)
{
int result = -1;
register DIM_UINT y = 0;
uint16 planarConfig;
if (tif == NULL) return result;
if (img == NULL) return result;
DIM_UINT sample;
DIM_UINT lineSize = getLineSizeInBytes( img );
TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planarConfig);
if ( (planarConfig == PLANARCONFIG_SEPARATE) || (img->i.samples == 1) )
{
for (sample=0; sample<img->i.samples; sample++)
{
DIM_UCHAR *p = (DIM_UCHAR *) img->bits[sample];
for(y=0; y<img->i.height; y++)
{
result = TIFFReadScanline(tif, p, y, sample);
p += lineSize;
} // for y
} // for sample
} // if planar
else // if image contain several samples in one same plane ex: RGBRGBRGB...
{
for (sample=0; sample<img->i.samples; sample++)
{
DIM_UCHAR *buf = (DIM_UCHAR *) _TIFFmalloc( TIFFScanlineSize ( tif ) );
DIM_UCHAR *p = (DIM_UCHAR *) img->bits[sample];
for(y=0; y<img->i.height; y++)
{
p = (DIM_UCHAR *) img->bits[sample] + (lineSize * y);
TIFFReadScanline(tif, buf, y, 0);
write_line_segment(p, buf, img, sample, img->i.width);
} // for y
_TIFFfree( buf );
} // for sample
}
return result;
}
//****************************************************************************
// TILED METHOD TIFF
//****************************************************************************
int read_tiled_tiff(TIFF *tif, TDimImageBitmap *img)
{
uint16 planarConfig;
if (tif == NULL) return 1;
if (img == NULL) return 1;
// if tiff is not tiled get out and never come back :-)
if( !TIFFIsTiled(tif) ) return 1;
uint32 columns, rows;
DIM_UCHAR *tile_buf;
register DIM_UINT x, y;
DIM_UINT sample;
DIM_UINT lineSize = getLineSizeInBytes( img );
TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planarConfig);
TIFFGetField(tif, TIFFTAG_TILEWIDTH, &columns);
TIFFGetField(tif, TIFFTAG_TILELENGTH, &rows);
tile_buf = (DIM_UCHAR*) _TIFFmalloc(TIFFTileSize(tif));
if (tile_buf == NULL) return 1;
uint32 tileW = columns, tileH = rows;
for (y=0; y<img->i.height; y+=rows)
{
if (y > img->i.height) break;
// the tile height may vary
if (img->i.height-y < rows) tileH = img->i.height-y;
tileW = columns;
for (x=0; x<(DIM_UINT)img->i.width; x+=columns)
{
register uint32 yi;
uint32 tW;
// the tile size is now treated by libtiff guys the
// way that the size stay on unchanged
if (img->i.width-x < columns) tW = img->i.width-x; else tW = tileW;
if ( (planarConfig == PLANARCONFIG_SEPARATE) || (img->i.samples == 1) )
{
for (sample=0; sample<img->i.samples; sample++)
{
if (!TIFFReadTile(tif, tile_buf, x, y, 0, sample)) break;
// now put tile into the image
for(yi = 0; yi < tileH; yi++)
{
DIM_UCHAR *p = (DIM_UCHAR *) img->bits[sample] + (lineSize * (y+yi));
_TIFFmemcpy(p+x, tile_buf+yi*tileW, tW);
}
} // for sample
} // if planar
else // if image contain several samples in one same plane ex: RGBRGBRGB...
{
if (!TIFFReadTile(tif, tile_buf, x, y, 0, 0)) break;
for (sample=0; sample<img->i.samples; sample++)
{
// now put tile into the image
for(yi = 0; yi < tileH; yi++)
{
DIM_UCHAR *p = (DIM_UCHAR *) img->bits[sample] + (lineSize * (y+yi));
write_line_segment(p+x, tile_buf+(yi*tileW*img->i.samples), img, sample, tW);
}
} // for sample
} // if not separate planes
} // for x
} // for y
_TIFFfree(tile_buf);
return 0;
}
//****************************************************************************
//*** TIFF READER
//****************************************************************************
int read_tiff_image(TDimFormatHandle *fmtHndl, TDimTiffParams *tifParams)
{
if (!areValidParams(fmtHndl, tifParams)) return 1;
TIFF *tif = tifParams->dimTiff;
TDimImageBitmap *img = fmtHndl->image;
uint32 height = 0;
uint32 width = 0;
uint16 bitspersample = 1;
uint16 samplesperpixel = 1;
uint32 rowsperstrip;
uint16 photometric = PHOTOMETRIC_MINISWHITE;
uint16 compression = COMPRESSION_NONE;
uint16 PlanarConfig;
unsigned int currentDir = 0;
currentDir = TIFFCurrentDirectory(tif);
// now must read correct page and set image parameters
if (currentDir != fmtHndl->pageNumber)
if (tifParams->subType != tstStk)
{
TIFFSetDirectory(tif, fmtHndl->pageNumber);
currentDir = TIFFCurrentDirectory(tif);
if (currentDir != fmtHndl->pageNumber) return 1;
getCurrentPageInfo( tifParams );
}
img->i = tifParams->info;
TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression);
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &PlanarConfig); // single image plane
// if image is PSIA then read and init it here
if (tifParams->subType == tstPsia)
return psiaReadPlane(fmtHndl, tifParams, fmtHndl->pageNumber, img);
// if image is Fluoview and contains 1..4 channels
if ( (tifParams->subType == tstFluoview) && (tifParams->fluoviewInfo.ch > 1) )
return fluoviewReadPlane( fmtHndl, tifParams, fmtHndl->pageNumber );
/*
DIM_UINT sample;
DIM_UINT size = getImgSizeInBytes( img );
for (sample=0; sample<img->i.samples; sample++)
{
if (img->bits[sample] != NULL) DimFree( img->bits[sample] );
img->bits[sample] = DimMalloc( size );
if (img->bits[sample] == NULL) return 1;
}
*/
if ( allocImg( fmtHndl, &img->i, img) != 0 ) return 1;
// if image is STK
if (tifParams->subType == tstStk)
return stkReadPlane(tifParams, fmtHndl->pageNumber, img);
if( !TIFFIsTiled(tif) )
read_scanline_tiff(tif, img);
else
read_tiled_tiff(tif, img);
// invert each pixel if PHOTOMETRIC_MINISWHITE
if (photometric == PHOTOMETRIC_MINISWHITE)
invertImg( img );
return 0;
}
//****************************************************************************
// TIFF WRITER
//****************************************************************************
int write_tiff_image(TDimFormatHandle *fmtHndl, TDimTiffParams *tifParams)
{
if (!areValidParams(fmtHndl, tifParams)) return 1;
TIFF *out = tifParams->dimTiff;
TDimImageBitmap *img = fmtHndl->image;
uint32 height;
uint32 width;
uint32 rowsperstrip = (uint32) -1;
uint16 bitspersample;
uint16 samplesperpixel;
uint16 photometric = PHOTOMETRIC_MINISBLACK;
uint16 compression;
uint16 planarConfig;
width = img->i.width;
height = img->i.height;
bitspersample = img->i.depth;
samplesperpixel = img->i.samples;
if (img->i.imageMode == DIM_RGB) photometric = PHOTOMETRIC_RGB;
if (img->i.imageMode == DIM_MULTI) photometric = PHOTOMETRIC_RGB;
if (samplesperpixel >= 2) photometric = PHOTOMETRIC_RGB;
if ( (img->i.imageMode == DIM_INDEXED) && (img->i.lut.count > 0) )
photometric = PHOTOMETRIC_PALETTE;
if ( (bitspersample == 1) && (samplesperpixel == 1) ) photometric = PHOTOMETRIC_MINISWHITE;
// handle standard width/height/bpp stuff
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
TIFFSetField(out, TIFFTAG_IMAGELENGTH, height);
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, bitspersample);
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(out, rowsperstrip));
if (img->i.imageMode == DIM_MULTI)
planarConfig = PLANARCONFIG_SEPARATE; // separated planes
else
planarConfig = PLANARCONFIG_CONTIG; // mixed planes
// now more tests for plane configuration
if (samplesperpixel > 3) planarConfig = PLANARCONFIG_SEPARATE;
if ( (samplesperpixel == 1) || (samplesperpixel == 3) )
planarConfig = PLANARCONFIG_CONTIG;
TIFFSetField(out, TIFFTAG_PLANARCONFIG, planarConfig); // separated planes
TIFFSetField(out, TIFFTAG_SOFTWARE, "DIMIN TIFF WRAPPER <www.dimin.net>");
//if( TIFFGetField( out, TIFFTAG_DOCUMENTNAME, &pszText ) )
//if( TIFFGetField( out, TIFFTAG_IMAGEDESCRIPTION, &pszText ) )
//if( TIFFGetField( out, TIFFTAG_DATETIME, &pszText ) )
//------------------------------------------------------------------------------
// Save resolution
//------------------------------------------------------------------------------
{
double rx = img->i.xRes, ry = img->i.yRes;
uint16 units = img->i.resUnits;
if ( (img->i.xRes == 0) && (img->i.yRes == 0) || (img->i.resUnits == 1) )
{
// Standard resolution some claim to be 72ppi... why not?
units = RESUNIT_INCH;
rx = 72.0;
ry = 72.0;
}
else
if (img->i.resUnits != 2)
{
if (img->i.resUnits == 0) { rx = pow(rx, -2); ry = pow(ry, -2); }
if (img->i.resUnits == 4) { rx = pow(rx, -1); ry = pow(ry, -1); }
if (img->i.resUnits == 5) { rx = pow(rx, -4); ry = pow(ry, -4); }
if (img->i.resUnits == 6) { rx = pow(rx, -7); ry = pow(ry, -7); }
if (img->i.resUnits == 7) { rx = pow(rx, 11); ry = pow(ry, 11); }
if (img->i.resUnits == 8) { rx = pow(rx, 8); ry = pow(ry, 8); }
if (img->i.resUnits == 9) { rx = pow(rx, 5); ry = pow(ry, 5); }
if (img->i.resUnits == 10) { rx = pow(rx, 0); ry = pow(ry, 0); }
}
TIFFSetField(out, TIFFTAG_RESOLUTIONUNIT, units);
TIFFSetField(out, TIFFTAG_XRESOLUTION, rx);
TIFFSetField(out, TIFFTAG_YRESOLUTION, ry);
}
TIFFFlushData(out);
//------------------------------------------------------------------------------
// palettes (image colormaps are automatically scaled to 16-bits)
//------------------------------------------------------------------------------
if ( (photometric == PHOTOMETRIC_PALETTE) && (img->i.lut.count > 0) )
{
uint16 *r, *g, *b;
uint16 nColors = img->i.lut.count;
r = (uint16 *) _TIFFmalloc(sizeof(uint16) * 3 * nColors);
g = r + nColors;
b = g + nColors;
for (int i=0; i<nColors; i++)
{
r[i] = (uint16) dimR( img->i.lut.rgba[i] ) * 256;
g[i] = (uint16) dimG( img->i.lut.rgba[i] ) * 256;
b[i] = (uint16) dimB( img->i.lut.rgba[i] ) * 256;
}
TIFFSetField(out, TIFFTAG_COLORMAP, r, g, b);
_TIFFfree(r);
}
TIFFFlushData(out);
//------------------------------------------------------------------------------
// compression
//------------------------------------------------------------------------------
switch(bitspersample) {
case 1 :
//compression = COMPRESSION_CCITTFAX4;
compression = COMPRESSION_NONE;
break;
case 8 :
case 24 :
case 32 :
compression = COMPRESSION_NONE;
break;
default :
compression = COMPRESSION_NONE;
break;
}
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
TIFFFlushData(out);
//------------------------------------------------------------------------------
// writing meta data
//------------------------------------------------------------------------------
write_tiff_metadata (fmtHndl, tifParams);
TIFFFlushData(out);
//------------------------------------------------------------------------------
// writing image
//------------------------------------------------------------------------------
// if separate palnes or only one sample
if ( (planarConfig == PLANARCONFIG_SEPARATE) || (samplesperpixel == 1) )
{
DIM_UINT sample;
DIM_UINT line_size = getLineSizeInBytes( img );
for (sample=0; sample<img->i.samples; sample++)
{
DIM_UCHAR *bits = (DIM_UCHAR *) img->bits[sample];
register uint32 y;
for (y = 0; y <height; y++)
{
TIFFWriteScanline(out, bits, y, sample);
TIFFFlushData(out);
bits += line_size;
} // for y
} // for samples
} // if separate planes
else
{ // if RGB image
DIM_UINT Bpp = (unsigned int) ceil( ((double) bitspersample) / 8.0 );
DIM_UCHAR *buffer = (DIM_UCHAR *) _TIFFmalloc(width * 3 * Bpp);
register DIM_UINT x, y;
for (y = 0; y < height; y++)
{
DIM_UCHAR *bufIn0 = ((DIM_UCHAR *) img->bits[0]) + y*width*Bpp;
DIM_UCHAR *bufIn1 = ((DIM_UCHAR *) img->bits[1]) + y*width*Bpp;
DIM_UCHAR *bufIn2 = ((DIM_UCHAR *) img->bits[2]) + y*width*Bpp;
if (img->i.depth <= 8)
{ // 8 bits
DIM_UCHAR *p = (DIM_UCHAR *) buffer;
for (x=0; x<width; x++)
{
p[0] = *(bufIn0 + x);
p[1] = *(bufIn1 + x);
p[2] = *(bufIn2 + x);
p += 3;
}
} // if 8 bit
else
{ // 16 bits
uint16 *p = (uint16 *) buffer;
uint16 *p0 = (uint16 *) bufIn0;
uint16 *p1 = (uint16 *) bufIn1;
uint16 *p2 = (uint16 *) bufIn2;
for (x=0; x<width; x++)
{
p[0] = *(p0 + x);
p[1] = *(p1 + x);
p[2] = *(p2 + x);
p += 3;
}
} // if 16 bit
// write the scanline to disc
TIFFWriteScanline(out, buffer, y, 0);
TIFFFlushData(out);
}
_TIFFfree(buffer);
}
//TIFFFlushData(out);
TIFFWriteDirectory( out );
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -