📄 dim_fluoview_format_io.cpp
字号:
/*****************************************************************************
TIFF FLUOVIEW IO
Copyright (c) 2004 by Dmitry V. Fedorov <www.dimin.net> <dima@dimin.net>
IMPLEMENTATION
Programmer: Dima V. Fedorov <mailto:dima@dimin.net> <http://www.dimin.net/>
History:
03/29/2004 22:23 - First creation
Ver : 1
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "dim_tiff_format.h"
static char* chanNames[4] = { "Red ", "Green", "Blue ", "Alpha" };
void change_0_to_n (char *str, long size);
void read_text_tag(TIFF *tif, TDimTiffIFD *ifd, DIM_UINT tag, MemIOBuf *outIOBuf);
//----------------------------------------------------------------------------
// PSIA MISC FUNCTIONS
//----------------------------------------------------------------------------
bool fluoviewIsTiffValid(TIFF *tif)
{
char *b_list = NULL;
int16 d_list_count;
int res[3] = {0,0,0};
if (tif == 0) return FALSE;
res[0] = TIFFGetField(tif, 34361, &d_list_count, &b_list);
res[1] = TIFFGetField(tif, 34362, &d_list_count, &b_list);
res[2] = TIFFGetField(tif, 34386, &d_list_count, &b_list);
if (res[0] == 1) return TRUE;
if (res[1] == 1) return TRUE;
if (res[2] == 1) return TRUE;
return FALSE;
}
bool fluoviewIsTiffValid(TDimTiffParams *tiffParams)
{
if (tiffParams == NULL) return FALSE;
// if tag 33629 exists then the file is valid STAK file
if (isTagPresentInFirstIFD( &tiffParams->ifds, 34361 ) == TRUE) return TRUE;
if (isTagPresentInFirstIFD( &tiffParams->ifds, 34362 ) == TRUE) return TRUE;
if (isTagPresentInFirstIFD( &tiffParams->ifds, 34386 ) == TRUE) return TRUE;
return FALSE;
}
void doSwabMMHEAD(MM_DIM_INFO *mmdi)
{
TIFFSwabLong ((uint32*) &mmdi->Size);
TIFFSwabDouble ((double*) &mmdi->Origin);
TIFFSwabDouble ((double*) &mmdi->Resolution);
}
void doSwabMMHEAD(MM_HEAD *mmh)
{
TIFFSwabShort((uint16*) &mmh->HeaderFlag);
TIFFSwabLong ((uint32*) &mmh->Data);
TIFFSwabLong ((uint32*) &mmh->NumberOfColors);
TIFFSwabLong ((uint32*) &mmh->MM_256_Colors);
TIFFSwabLong ((uint32*) &mmh->MM_All_Colors);
TIFFSwabLong ((uint32*) &mmh->CommentSize);
TIFFSwabLong ((uint32*) &mmh->Comment);
TIFFSwabLong ((uint32*) &mmh->SpatialPosition);
TIFFSwabShort((uint16*) &mmh->MapType);
TIFFSwabLong ((uint32*) &mmh->MapMin);
TIFFSwabLong ((uint32*) &mmh->MapMax);
TIFFSwabLong ((uint32*) &mmh->MinValue);
TIFFSwabLong ((uint32*) &mmh->MaxValue);
TIFFSwabLong ((uint32*) &mmh->Map);
TIFFSwabLong ((uint32*) &mmh->Gamma);
TIFFSwabLong ((uint32*) &mmh->Offset);
TIFFSwabLong ((uint32*) &mmh->ThumbNail);
TIFFSwabLong ((uint32*) &mmh->UserFieldSize);
TIFFSwabLong ((uint32*) &mmh->UserFieldHandle);
doSwabMMHEAD(&mmh->Gray);
for (int i=0; i<SPATIAL_DIMENSION; ++i)
doSwabMMHEAD(&mmh->DimInfo[i]);
}
void printMM_DIM_INFO(MM_DIM_INFO *mmdi)
{
printf( "\nMM_DIM_INFO Name: %s\n", mmdi->Name);
printf( "MM_DIM_INFO size: %d\n", mmdi->Size);
printf( "MM_DIM_INFO origin: %f\n", mmdi->Origin);
printf( "MM_DIM_INFO resolution: %f\n", mmdi->Resolution);
printf( "MM_DIM_INFO Units: %s\n", mmdi->Units);
}
void printMMHEADER(MM_HEAD *mmh)
{
printf( "\nMMHEAD HeaderFlag: %.4X\n", mmh->HeaderFlag);
printf( "\nMMHEAD ImageType: %.1X\n", mmh->ImageType);
printf( "\nMMHEAD Name: %s\n", mmh->Name);
printf( "\nMMHEAD Status: %.1X\n", mmh->Status);
printf( "\nMMHEAD Data: %.8X\n", mmh->Data);
printf( "\nMMHEAD NumberOfColors: %.8X\n", mmh->NumberOfColors);
printf( "\nMMHEAD MM_256_Colors: %.8X\n", mmh->MM_256_Colors);
printf( "\nMMHEAD MM_All_Colors: %.8X\n", mmh->MM_All_Colors);
printf( "\nMMHEAD CommentSize: %.8X\n", mmh->CommentSize);
printf( "\nMMHEAD Comment: %.8X\n", mmh->Comment);
for (int i=0; i<SPATIAL_DIMENSION; ++i)
printMM_DIM_INFO(&mmh->DimInfo[i]);
}
int fluoviewGetInfo (TDimTiffParams *tiffParams)
{
if (tiffParams == NULL) return 1;
if (tiffParams->dimTiff == NULL) return 1;
if (tiffParams->ifds.count <= 0) return 1;
TDimFluoviewInfo *fvi = &tiffParams->fluoviewInfo;
DIM_UCHAR *buf = NULL;
uint32 size, type;
MM_HEAD *fvInfo;
if (!isTagPresentInFirstIFD( &tiffParams->ifds, MMHEADER )) return 1;
readTiffTag (tiffParams->dimTiff, &tiffParams->ifds.ifds[0], MMHEADER, size, type, &buf);
if ( (size <= 0) || (buf == NULL) ) return 1;
//if (swabflag)
if (bigendian) doSwabMMHEAD((MM_HEAD *) buf);
fvi->head = * (MM_HEAD *) buf;
freeTiffTagBuf( &buf );
fvInfo = &fvi->head;
fvi->ch = 1;
fvi->pages = 1;
fvi->t_frames = 1;
fvi->z_slices = 1;
//---------------------------------------------------------------
// retreive dimension parameters
// Typical dimension names include "X", "Y", "Z", "T", "Ch", "Ani"
// Fluoview order is: XYZTC -> we obtain XYCZT
//---------------------------------------------------------------
int d;
for (d=0; d<SPATIAL_DIMENSION; d++)
{
if ( strncmp(fvInfo->DimInfo[d].Name, "Ch", 2 ) == 0 )
fvi->ch = fvInfo->DimInfo[d].Size;
else
if ( strncmp(fvInfo->DimInfo[d].Name, "T", 1 ) == 0 )
fvi->t_frames = fvInfo->DimInfo[d].Size;
else
if ( strncmp(fvInfo->DimInfo[d].Name, "Z", 1 ) == 0 )
{
fvi->z_slices = fvInfo->DimInfo[d].Size;
fvi->zR = fvInfo->DimInfo[d].Resolution;
}
else
if ( strncmp(fvInfo->DimInfo[d].Name, "X", 1 ) == 0 )
fvi->xR = fvInfo->DimInfo[d].Resolution;
else
if ( strncmp(fvInfo->DimInfo[d].Name, "Y", 1 ) == 0 )
fvi->yR = fvInfo->DimInfo[d].Resolution;
}
fvi->pages_tiff = tiffParams->info.number_pages;
fvi->pages = tiffParams->info.number_pages / fvi->ch;
tiffParams->info.number_pages = fvi->pages;
tiffParams->info.samples = fvi->ch;
if (tiffParams->info.samples > 1)
tiffParams->info.imageMode = DIM_RGB;
else
tiffParams->info.imageMode = DIM_GRAYSCALE;
uint16 bitspersample = 1;
TIFFGetField(tiffParams->dimTiff, TIFFTAG_BITSPERSAMPLE, &bitspersample);
tiffParams->info.depth = bitspersample;
//--------------------------------------------------------------------
// obtain correct sample to channel LUT
//--------------------------------------------------------------------
//int samp_lut[4] = {0, 1, 2, 3};
int *samp_lut = fvi->sample_lut;
int i;
for (i=0; i<4; i++) samp_lut[i] = i;
TDimTiffIFD *ifd = &tiffParams->ifds.ifds[0];
TIFF *tif = tiffParams->dimTiff;
if (isTagPresentInIFD ( ifd, 270 ) == TRUE )
{
uint32 buf_size;
uint32 buf_type;
DIM_UCHAR *buf = NULL;
int ch_usage[4] = {0, 0, 0, 0};
readTiffTag (tif, ifd, 270, buf_size, buf_type, &buf);
change_0_to_n ((char *) buf, buf_size);
int i=0, i2;
char *line, str[100];
int r,g,b, chOut;
for (i=0; i<4; i++)
{
chOut = -1;
sprintf(str, "[LUT Ch%d]", i);
line = strstr( (char *) buf, str );
if (line != NULL) {
line = strstr( line, "RGB 255=" );
sscanf( line, "RGB 255=%d\t%d\t%d", &r, &g, &b );
if ( (r>=g) && (r>=b) ) chOut = 0;
if ( (g>=r) && (g>=b) ) chOut = 1;
if ( (b>=g) && (b>=r) ) chOut = 2;
}
if (chOut == -1) chOut = samp_lut[fvi->ch];
if (ch_usage[chOut] == 1)
for (i2=0; i2<4; i2++)
if (ch_usage[i2] == 0) { chOut = i2; break; }
// channel accepted
ch_usage[chOut] = 1;
samp_lut[i] = chOut;
}
freeTiffTagBuf( (DIM_UCHAR **) &buf );
}
return 0;
}
// in fluoview luts are saved as INI text in tag: 270 - Image Description
void fluoviewInitPalette( TDimTiffParams *tiffParams, TDimImageInfo *info )
{
uint32 buf_size;
uint32 buf_type;
DIM_UCHAR *buf = NULL;
TIFF *tif = tiffParams->dimTiff;
TDimTiffIFD *ifd = &tiffParams->ifds.ifds[0];
if (tif == NULL) return;
if (info == NULL) return;
if (tiffParams->subType != tstFluoview) return;
if (tiffParams->fluoviewInfo.ch > 1) return;
if (isTagPresentInIFD ( ifd, 270 ) != TRUE ) return;
readTiffTag (tif, ifd, 270, buf_size, buf_type, &buf);
change_0_to_n ((char *) buf, buf_size);
int i=0;
char *line, str[100];
int r,g,b;
info->lut.count = 0;
for (i=0; i<256; i++) info->lut.rgba[i] = i*256;
line = strstr( (char *) buf, "[LUT Ch0]" );
if (line != NULL)
for (i=0; i<256; i++)
{
sprintf(str, "RGB %d=", i);
line = strstr( line, str );
sprintf(str, "RGB %d=%%d\t%%d\t%%d\n", i);
sscanf( line, str, &r, &g, &b );
info->lut.rgba[i] = dimRGB( r, g, b );
}
info->lut.count = 256;
freeTiffTagBuf( (DIM_UCHAR **) &buf );
}
//----------------------------------------------------------------------------
// READ/WRITE FUNCTIONS
//----------------------------------------------------------------------------
DIM_UINT fluoviewReadPlane( TDimFormatHandle *fmtHndl, TDimTiffParams *tiffParams, int plane )
{
if (tiffParams == 0) return 1;
if (tiffParams->dimTiff == 0) return 1;
if (tiffParams->subType != tstFluoview) return 1;
uint16 bitspersample = 1;
TIFF *tif = tiffParams->dimTiff;
TDimFluoviewInfo *fvi = &tiffParams->fluoviewInfo;
TDimImageInfo *ii = &tiffParams->info;
if (tif == NULL) return 1;
TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
ii->samples = fvi->ch;
if (fvi->ch==2) ii->samples = 3;
if (ii->samples > 1)
ii->imageMode = DIM_RGB;
else
ii->imageMode = DIM_GRAYSCALE;
ii->depth = bitspersample;
if (bitspersample == 16) ii->pixelType = DIM_TAG_SHORT;
int sample;
TDimImageBitmap *img = fmtHndl->image;
if ( allocImg( fmtHndl, ii, img) != 0 ) return 1;
// init all image planes
for (sample=0; sample<ii->samples; sample++)
memset( img->bits[sample], 0, getImgSizeInBytes(img) );
//--------------------------------------------------------------------
// read data
//--------------------------------------------------------------------
int *samp_lut = fvi->sample_lut;
DIM_UINT lineSize = getLineSizeInBytes( img );
for (sample=0; sample<fvi->ch; sample++)
{
// switch to correct page in original TIFF
int dirNum = fmtHndl->pageNumber + sample * ( fvi->pages_tiff / fvi->ch );
TIFFSetDirectory( tif, dirNum );
if( TIFFIsTiled(tif) ) continue;
DIM_UCHAR *p = (DIM_UCHAR *) img->bits[ samp_lut[sample] ];
register DIM_UINT y = 0;
for(y=0; y<img->i.height; y++)
{
TIFFReadScanline(tif, p, y, 0);
p += lineSize;
} // for y
} // for sample
TIFFSetDirectory(tif, fmtHndl->pageNumber);
return 0;
}
//----------------------------------------------------------------------------
// METADATA TEXT FUNCTIONS
//----------------------------------------------------------------------------
void fluoviewWriteTextMeta(TDimTiffParams *tiffParams, MemIOBuf *outIOBuf)
{
if (tiffParams == NULL) return;
if (tiffParams->subType != tstFluoview) return;
TDimFluoviewInfo *fvi = &tiffParams->fluoviewInfo;
MM_HEAD *fvInfo = &fvi->head;
char text[1024];
sprintf(text, "[Fluoview Metadata]\n");
MemIO_WriteProc( (thandle_t) outIOBuf, text, strlen(text) );
sprintf(text, "Number of Channels: %d\n", fvi->ch );
MemIO_WriteProc( (thandle_t) outIOBuf, text, strlen(text) );
sprintf(text, "Number of Time Frames: %d\n", fvi->t_frames );
MemIO_WriteProc( (thandle_t) outIOBuf, text, strlen(text) );
sprintf(text, "Number of Z slices: %d\n", fvi->z_slices );
MemIO_WriteProc( (thandle_t) outIOBuf, text, strlen(text) );
int d;
for (d=0; d<SPATIAL_DIMENSION; d++)
{
if ( strncmp(fvInfo->DimInfo[d].Name, "Z", 1 ) == 0 )
{
sprintf(text, "Z Resolution: %.6f %s\n\n", fvInfo->DimInfo[d].Resolution, fvInfo->DimInfo[d].Units );
MemIO_WriteProc( (thandle_t) outIOBuf, text, strlen(text)-1 );
}
else
if ( strncmp(fvInfo->DimInfo[d].Name, "X", 1 ) == 0 )
{
sprintf(text, "X Resolution: %.6f %s\n\n", fvInfo->DimInfo[d].Resolution, fvInfo->DimInfo[d].Units );
MemIO_WriteProc( (thandle_t) outIOBuf, text, strlen(text)-1 );
}
else
if ( strncmp(fvInfo->DimInfo[d].Name, "Y", 1 ) == 0 )
{
sprintf(text, "Y Resolution: %.6f %s\n\n", fvInfo->DimInfo[d].Resolution, fvInfo->DimInfo[d].Units );
MemIO_WriteProc( (thandle_t) outIOBuf, text, strlen(text)-1 );
}
}
//----------------------------------------------------------------------------
// Now read standard tags and parse them
//----------------------------------------------------------------------------
int *samp_lut = fvi->sample_lut;
// Special code for tag 270 in fluoview - remove palettes
TDimTiffIFD *ifd = &tiffParams->ifds.ifds[0];
TIFF *tif = tiffParams->dimTiff;
uint32 buf_size=0;
uint32 buf_type=0;
DIM_UCHAR *buf = NULL;
DIM_UINT tag = 270;
char str[100];
char *line;
if (isTagPresentInIFD ( ifd, tag ) == TRUE )
{
readTiffTag (tif, ifd, tag, buf_size, buf_type, &buf);
change_0_to_n ((char *) buf, buf_size);
line = strstr( (char *) buf, "[LUT Ch0]" );
if (line != NULL) {
line[0] = 0;
buf_size = strlen( (char *) buf );
}
}
int i;
for (i=0; i<fvi->ch; i++)
{
sprintf(text, "Channel %d Dye=", i+1 );
line = strstr( (char *) buf, text );
if (line != NULL) {
sprintf(text, "Channel %d Dye=%%s\n", i+1 );
sscanf( line, text, str );
sprintf(text, "%s: %s\n", chanNames[samp_lut[i]], str );
MemIO_WriteProc( (thandle_t) outIOBuf, text, strlen(text) );
}
}
sprintf(text, " \n" );
MemIO_WriteProc( (thandle_t) outIOBuf, text, strlen(text) );
//----------------------------------------------------------------------------
// Now read standard tags and reformat them
//----------------------------------------------------------------------------
read_text_tag(tif, ifd, 285, outIOBuf);
read_text_tag(tif, ifd, 270, outIOBuf);
if (buf != NULL) MemIO_WriteProc( (thandle_t) outIOBuf, buf, buf_size );
freeTiffTagBuf( (DIM_UCHAR **) &buf );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -