⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dim_fluoview_format_io.cpp

📁 Digital Notebook Source Code v1.1.0 [
💻 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 + -