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

📄 dim_stk_format_io.cpp

📁 Digital Notebook Source Code v1.1.0 [
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************
  TIFF STK 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/>
    
  TODO:
    At this point it's not supporting more then one sample per pixel...
    Check compression related to stripes, we might change it later

  History:
    03/29/2004 22:23 - First creation
    09/28/2005 23:10 - fixed bugs for bigendian architecture
        
  Ver : 2
*****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include <string>

// Disables Visual Studio 2005 warnings for deprecated code#ifdef WIN32   #pragma warning(disable:4996)#endif

#include "memio.h"
#include "dim_tiff_format.h"
#include "dim_stk_format.h"

#define HOURS_PER_DAY 24
#define MINS_PER_HOUR 60
#define SECS_PER_MIN  60
#define MSECS_PER_SEC 1000
#define MINS_PER_DAY  (HOURS_PER_DAY * MINS_PER_HOUR)
#define SECS_PER_DAY  (MINS_PER_DAY * SECS_PER_MIN)
#define MSECS_PER_DAY (SECS_PER_DAY * MSECS_PER_SEC)

//----------------------------------------------------------------------------
// STK MISC FUNCTIONS
//----------------------------------------------------------------------------
void JulianToYMD(unsigned long julian, unsigned short& year, unsigned char& month, unsigned char& day)
{
  long  a, b, c, d, e, alpha;
  long  z = julian + 1;

  // dealing with Gregorian calendar reform
  if (z < 2299161L) {
    a = z;
  } else {
    alpha = (long) ((z - 1867216.25) / 36524.25);
    a = z + 1 + alpha - alpha / 4;
  }

  b = ( a > 1721423L ? a + 1524 : a + 1158 );
  c = (long) ((b - 122.1) / 365.25);
  d = (long) (365.25 * c);
  e = (long) ((b - d) / 30.6001);

  day   = (unsigned char) (b - d - (long)(30.6001 * e));
  month = (unsigned char) ((e < 13.5) ? e - 1 : e - 13) - 1; // dima: sub 1 to match Date/Time TIFF tag
  year  = (short)         ((month > 2.5 ) ? (c - 4716) : c - 4715);
}

unsigned long YMDToJulian(unsigned short year, unsigned char month, unsigned char day)
{
  short a, b = 0;
  short work_year = year;
  short work_month = month;
  short work_day = day;

  // correct for negative year
  if (work_year < 0) {
    work_year++;
  }

  if (work_month <= 2) {
    work_year--;
    work_month += (short)12;
  }

  // deal with Gregorian calendar
  if (work_year*10000. + work_month*100. + work_day >= 15821015.) {
    a = (short)(work_year/100.);
    b = (short)(2 - a + a/4);
  }

  return  (long) (365.25*work_year) +
          (long) (30.6001 * (work_month+1)) +
          work_day + 1720994L + b;
}

void divMod(int Dividend, int Divisor, int &Result, int &Remainder)
{
  Result    = (int) ( ((double) Dividend) / ((double) Divisor) );
  Remainder = Dividend % Divisor;
}

// this convert miliseconds since midnight into hour/minute/second
void MiliMidnightToHMS(unsigned long ms, unsigned char& hour, unsigned char& minute, unsigned char& second)
{
  int h, m, s, fms;
  int mc, msc;

  divMod(ms,  SECS_PER_MIN * MSECS_PER_SEC, mc, msc);
  divMod(mc,  MINS_PER_HOUR, h, m);
  divMod(msc, MSECS_PER_SEC, s, fms);

  hour = h;
  minute = m;
  second = s;
}


//----------------------------------------------------------------------------
// STK UTIL FUNCTIONS
//----------------------------------------------------------------------------

bool stkAreValidParams(TDimTiffParams *tiffParams)
{
  if (tiffParams == NULL) return FALSE;
  if (tiffParams->dimTiff == NULL) return FALSE;

  return TRUE;
}

long stkGetNumPlanes(TIFF *tif)
{
  double *d_list = NULL;
  long *l_list = NULL;
  int16   d_list_count[3];
  int res[3] = {0,0,0};

  if (tif == 0) return 0;

  res[0] = TIFFGetField(tif, 33629, &d_list_count[0], &d_list);
  res[1] = TIFFGetField(tif, 33630, &d_list_count[1], &d_list);
  res[2] = TIFFGetField(tif, 33631, &d_list_count[2], &l_list);

  // if tag 33629 exists then the file is valid STAK file
  if (res[0] == 1) return d_list_count[0];
  if (res[1] == 1) return d_list_count[1];
  if (res[2] == 1) return d_list_count[2];

  return 1;
}

bool stkIsTiffValid(TIFF *tif)
{
  double *d_list = NULL;
  long *l_list = NULL;
  int16   d_list_count;
  int res[3] = {0,0,0};

  if (tif == 0) return FALSE;

  res[0] = TIFFGetField(tif, 33629, &d_list_count, &d_list);
  res[1] = TIFFGetField(tif, 33630, &d_list_count, &d_list);
  res[2] = TIFFGetField(tif, 33631, &d_list_count, &l_list);

  // if tag 33629 exists then the file is valid STAK file
  if (res[0] == 1) return TRUE;
  if (res[1] == 1) return TRUE;
  if (res[2] == 1) return TRUE;

  return FALSE;
}

bool stkIsTiffValid(TDimTiffParams *tiffParams)
{
  if (tiffParams == NULL) return FALSE;

  // if tag 33629 exists then the file is valid STAK file
  if (isTagPresentInFirstIFD( &tiffParams->ifds, 33629 ) == TRUE) return TRUE;
  if (isTagPresentInFirstIFD( &tiffParams->ifds, 33630 ) == TRUE) return TRUE;
  if (isTagPresentInFirstIFD( &tiffParams->ifds, 33631 ) == TRUE) return TRUE;

  return FALSE;
}

void stkGetOffsets(TIFF *tif, TDimTiffParams *tiffParams )
{
  /*
  the default libtiff strip reading is not good enough since it only gives us strip offsets for 
  the first plane although all the offsets for all the planes are actually stored
  so for uncompressed images use default and for LZW the custom methods
  */
  
  TDimStkInfo *stkInfo = &tiffParams->stkInfo;
  stkInfo->strips_per_plane = TIFFNumberOfStrips( tif );

  if (stkInfo->strip_offsets != NULL) _TIFFfree(stkInfo->strip_offsets);
  stkInfo->strip_offsets = NULL;
  if (stkInfo->strip_bytecounts != NULL) _TIFFfree(stkInfo->strip_bytecounts);
  stkInfo->strip_bytecounts = NULL;

  if (tiffParams == NULL) return;
  if (tiffParams->dimTiff == NULL) return;
  if (tiffParams->subType != tstStk) return;

  TDimTiffIFD *ifd = &tiffParams->ifds.ifds[0];
  int N = tiffParams->stkInfo.metaData.N;
  uint32 tag = 0;

  // -----------------------------
  // read Strip Offsets
  // -----------------------------
  tag = 273;
  if (isTagPresentInFirstIFD( &tiffParams->ifds, tag ) == TRUE)
  {
    uint32 *buf = NULL;
    uint32 size=0, type=0;

    readTiffTag ( tif, ifd, tag, size, type, (DIM_UCHAR **) &buf );
    if (buf != NULL) 
    {
      stkInfo->strip_offsets = (uint32 *) _TIFFmalloc( size );
      _TIFFmemcpy( stkInfo->strip_offsets, buf, size );
      _TIFFfree( buf );
    }
  } // strip offsets
  
  // -----------------------------
  // read strip_bytecounts also
  // -----------------------------
  tag = 279;
  if (isTagPresentInFirstIFD( &tiffParams->ifds, tag ) == TRUE)
  {
    uint32 *buf = NULL;
    uint32 size=0, type=0;

    readTiffTag ( tif, ifd, tag, size, type, (DIM_UCHAR **) &buf );
    if (buf != NULL) 
    {
      stkInfo->strip_bytecounts = (uint32 *) _TIFFmalloc( size );
      _TIFFmemcpy( stkInfo->strip_bytecounts, buf, size );
      _TIFFfree( buf );
    }
  } // strip_bytecounts
}

void stkClearOffsets(TDimStkInfo *stkInfo)
{
  if ( (stkInfo->strip_offsets != NULL) && (stkInfo->strips_per_plane > 0) )
    _TIFFfree(stkInfo->strip_offsets);

  if ( (stkInfo->strip_bytecounts != NULL) && (stkInfo->strips_per_plane > 0) )
    _TIFFfree(stkInfo->strip_bytecounts);

  stkInfo->strip_offsets    = NULL;
  stkInfo->strip_bytecounts = NULL;
  stkInfo->strips_per_plane = 0;
}


//----------------------------------------------------------------------------
// PARSE UIC TAGS
//----------------------------------------------------------------------------

// UIC2Tag - 33629  
//At the indicated offset, there is a table of 6*N LONG values 
//indicating for each plane in order: 
//Z distance (numerator), Z distance (denominator), 
//creation date, creation time, modification date, modification time.
void stkParseUIC2Tag( TDimTiffParams *tiffParams )
{
  if (tiffParams == NULL) return;
  if (tiffParams->dimTiff == NULL) return;
  if (tiffParams->subType != tstStk) return;

  TDimStkInfo *stkInfo = &tiffParams->stkInfo;
  TDimTiffIFD *ifd = &tiffParams->ifds.ifds[0];

  // read UIC2
  int tag = 33629;
  if (isTagPresentInFirstIFD( &tiffParams->ifds, tag ) != TRUE) return;
  else
  {
    long i;
    long N = stkInfo->metaData.N;
    DIM_UINT32 *buf = NULL;
    readTiffCustomTag (tiffParams->dimTiff, ifd, tag, 6*N*sizeof(DIM_INT32), DIM_TAG_LONG, (DIM_UCHAR **) &buf);
    if (buf == NULL) return;

    for (i=0; i<N; i++)
    {
      stkInfo->metaData.zDistance[i].num    = buf[i*6+0];
      stkInfo->metaData.zDistance[i].den    = buf[i*6+1];
      stkInfo->metaData.creationDate[i]     = buf[i*6+2];
      stkInfo->metaData.creationTime[i]     = buf[i*6+3];
      stkInfo->metaData.modificationDate[i] = buf[i*6+4];
      stkInfo->metaData.modificationTime[i] = buf[i*6+5];
    }

    freeTiffTagBuf( (DIM_UCHAR **) &buf );
  }
}


// UIC3Tag - 33630 
//A table of 2*N LONG values indicating for each plane in order: 
//wavelength (numerator), wavelength (denominator).
void stkParseUIC3Tag( TDimTiffParams *tiffParams )
{
  if (tiffParams == NULL) return;
  if (tiffParams->dimTiff == NULL) return;
  if (tiffParams->subType != tstStk) return;

  TDimStkInfo *stkInfo = &tiffParams->stkInfo;
  TDimTiffIFD *ifd = &tiffParams->ifds.ifds[0];

  // read UIC3
  int tag = 33630;
  if (isTagPresentInFirstIFD( &tiffParams->ifds, tag ) != TRUE) return;
  else
  {
    long i=0;
    long N = tiffParams->stkInfo.metaData.N;
    DIM_UINT32 *buf = NULL;
 
    readTiffCustomTag (tiffParams->dimTiff, ifd, tag, 2*N*sizeof(DIM_UINT32), DIM_TAG_LONG, (DIM_UCHAR **) &buf);
    if (buf == NULL) return;

    for (i=0; i<N; i++)
    {
      stkInfo->metaData.wavelength[i].num = buf[i*2];
      stkInfo->metaData.wavelength[i].den = buf[i*2+1];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -