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

📄 dim_tiff_format_io.cpp

📁 Digital Notebook Source Code v1.1.0 [
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
  TIFF 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:
    4) read preview image in RGB 8bit

  History:
    03/29/2004 22:23 - First creation
        
  Ver : 1
*****************************************************************************/

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

#include "memio.h"
#include "dim_tiny_tiff.h"
#include "dim_tiff_format.h"

int invertSample(TDimImageBitmap *img, int sample);
int invertImg(TDimImageBitmap *img);

// must include these guys here if not no access to internal TIFF structs
#include "dim_tiny_tiff.cpp"
#include "dim_stk_format_io.cpp"
#include "dim_psia_format_io.cpp"
#include "dim_fluoview_format_io.cpp"

//****************************************************************************
// util procs
//****************************************************************************
int invertSample(TDimImageBitmap *img, int sample)
{
  if (img == 0) return -1;
  int i;
  long size = img->i.width * img->i.height; 

  DIM_UINT max_uint16 = (DIM_UINT16) -1;
  DIM_UINT max_uchar = (DIM_UCHAR) -1;

  if (img->i.depth == 16) 
  {
    uint16 *p = (uint16 *) img->bits[sample];  

    for (i=0; i<size; i++) {
      *p = max_uint16 - *p;
      p++;
    }

  }
  
  if (img->i.depth == 8) // 8bit
  {
    DIM_UCHAR *p = (DIM_UCHAR *) img->bits[sample];  
    for (i=0; i<size; i++) {
      *p = max_uchar - *p;
      p++;
    }
  }

  return 0;
}

int invertImg(TDimImageBitmap *img)
{
  if (img == 0) return -1;

  DIM_UINT sample;
  for (sample=0; sample<img->i.samples; sample++)
  {
    invertSample(img, sample);
  }

  return 0;
}


//****************************************************************************
// *FILE handlers
//****************************************************************************
/*
static tsize_t tiff_read(thandle_t handle,tdata_t data,tsize_t size) 
{
  FILE *stream = (FILE*) handle;
  return (tsize_t) fread(data, sizeof(unsigned char), size, stream);
}

static tsize_t tiff_write(thandle_t handle,tdata_t data,tsize_t size) 
{
  FILE *stream = (FILE*) handle;
  return (tsize_t) fwrite(data, sizeof(unsigned char), size, stream);
}

static toff_t tiff_seek(thandle_t handle, toff_t offset, int whence) 
{
  FILE *stream = (FILE*) handle;
  if ( fseek( stream, offset, whence ) == 0)
    return ftell( stream );
  else
    return 0;
}

static int tiff_close(thandle_t handle) 
{
  FILE *stream = (FILE*) handle;
  fflush( stream );
  fclose( stream );
  return 0;
}

static toff_t tiff_size(thandle_t handle) 
{
  uint size, cur_pos;
  FILE *stream = (FILE*) handle;

  cur_pos = ftell( stream );
  fseek( stream, 0, SEEK_END );
  size = ftell( stream );
  fseek( stream, cur_pos, SEEK_SET );
  return size;
}

static int tiff_mmap(thandle_t handle,tdata_t* data,toff_t* size) 
{
  handle=handle; data=data; size=size;
  return (int) MAP_FAILED;
}

static void tiff_unmap(thandle_t handle, tdata_t data, toff_t size) 
{
  handle=handle; data=data; size=size;
}
*/

//****************************************************************************
// MISC
//****************************************************************************

bool areValidParams(TDimFormatHandle *fmtHndl, TDimTiffParams *tifParams)
{
  if (fmtHndl == NULL) return FALSE;
  if (tifParams == NULL) return FALSE;
  if (tifParams->dimTiff == NULL) return FALSE;
  if (fmtHndl->image == NULL) return FALSE;

  return TRUE;
}

void init_image_palette( TIFF *tif, TDimImageInfo *info )
{
  DIM_UINT i;
  uint16 photometric = PHOTOMETRIC_MINISWHITE;
  uint16 bitspersample = 1;

  if (tif == NULL) return;
  if (info == NULL) return;
  
  TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
  TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);

  info->lut.count = 0;
  for (i=0; i<256; i++) info->lut.rgba[i] = i*256;
  
  if (photometric == PHOTOMETRIC_PALETTE)
  { // palette
    uint16 *red;
    uint16 *green;
    uint16 *blue;
    DIM_UINT num_colors = ( 1<<bitspersample );
    if (num_colors > 256) num_colors = 256;    

    TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue);

    for (i=0; i<num_colors; i++)
    {
      info->lut.rgba[i] = dimRGB( red[i]/256, green[i]/256, blue[i]/256 );
    } // for colors

    info->lut.count = num_colors;
  } // if paletted

}

//****************************************************************************
// META DATA
//****************************************************************************

DIM_UINT read_one_tag (TDimFormatHandle *fmtHndl, TDimTiffParams *tifParams, int tag)
{
  if (!areValidParams(fmtHndl, tifParams)) return 1;
  if (tifParams->ifds.count == 0) return 1;

  if (fmtHndl->pageNumber >= tifParams->ifds.count) fmtHndl->pageNumber = 0;
  TIFF *tif = tifParams->dimTiff;
  TDimTiffIFDs *ifds = &tifParams->ifds;

  DIM_UCHAR *buf = NULL;
  uint32 buf_size;
  uint32 buf_type;

  if ( (tifParams->subType == tstStk) && (tag == 33629) ) // stk 33629 got custom size 6*N
  {
    buf_type = DIM_TAG_LONG;
    DIM_INT32 count = getTiffTagCount(tif, &ifds->ifds[fmtHndl->pageNumber], tag);
    buf_size = ( count * 6 ) * tag_size_bytes[buf_type];
    readTiffCustomTag (tif, &ifds->ifds[fmtHndl->pageNumber], tag, buf_size, buf_type, (DIM_UCHAR **) &buf);
  }
  else
    readTiffTag (tif, &ifds->ifds[fmtHndl->pageNumber], tag, buf_size, buf_type, (DIM_UCHAR **) &buf);



  if ( (buf_size == 0) || (buf == NULL) ) return 1;
  else
  {
    // now add tag into structure
    TDimTagItem item;

    item.tagGroup  = DIM_META_TIFF_TAG;
    item.tagId     = tag;
    item.tagType   = buf_type;
    item.tagLength = buf_size / tag_size_bytes[buf_type];
    item.tagData   = buf;

    addMetaTag( &fmtHndl->metaData, item);
  }

  return 0;
}

DIM_UINT read_tiff_metadata (TDimFormatHandle *fmtHndl, TDimTiffParams *tifParams, int group, int tag, int type)
{
  if (!areValidParams(fmtHndl, tifParams)) return 1;

  if (group == DIM_META_BIORAD) return 1;
  
  if (fmtHndl->pageNumber >= tifParams->ifds.count) fmtHndl->pageNumber = 0;

  // first read custom formatted tags
  if (tifParams->subType == tstStk)
    stkReadMetaMeta (fmtHndl, group, tag, type);

  if (tag != -1)
    return read_one_tag ( fmtHndl, tifParams, tag );

  if ( (group == -1) || (group == DIM_META_TIFF_TAG) )
  {
    DIM_UINT i;
    TDimTiffIFD *ifd = &tifParams->ifds.ifds[fmtHndl->pageNumber];

    for (i=0; i<ifd->count; i++ )
    {
      if (type == -1)
      {
        if ( (ifd->entries[i].tag > 532) &&
             (ifd->entries[i].tag != 50434)

           ) read_one_tag ( fmtHndl, tifParams, ifd->entries[i].tag );    
    
        switch( ifd->entries[i].tag ) 
        {
          case 269: //DocumentName
          case 270: //ImageDescription
          case 271: //Make
          case 272: //Model
          case 285: //PageName
          case 305: //Software
          case 306: //DateTime
          case 315: //Artist
          case 316: //HostComputer
            read_one_tag ( fmtHndl, tifParams, ifd->entries[i].tag );
            break;
        } // switch
      } // type == -1
      else
      {
        if (ifd->entries[i].type == type)
          read_one_tag ( fmtHndl, tifParams, ifd->entries[i].tag );

      } // type != -1

    } // for i<ifd count
  } // if no group

  return 0;
}

void change_0_to_n (char *str, long size)
{
  long i;

  for (i=0; i<size; i++)
  {
    if (str[i] == '\0') str[i] = '\n'; 
  }
}

void write_title_text(const char *text, MemIOBuf *outIOBuf)
{
  char title[1024];
  sprintf(title, "\n[%s]\n\n", text);
  MemIO_WriteProc( (thandle_t) outIOBuf, title, strlen(title)-1 );
}

void read_text_tag(TIFF *tif, TDimTiffIFD *ifd, DIM_UINT tag, MemIOBuf *outIOBuf, const char *text)
{
  uint32 buf_size;
  uint32 buf_type;  
  DIM_UCHAR *buf = NULL;
  
  if (isTagPresentInIFD ( ifd, tag ) == TRUE )
  {
    write_title_text(text, outIOBuf);
    readTiffTag (tif, ifd, tag, buf_size, buf_type, &buf);
    change_0_to_n ((char *) buf, buf_size);
    MemIO_WriteProc( (thandle_t) outIOBuf, buf, buf_size );
    freeTiffTagBuf( (DIM_UCHAR **) &buf );
  }
}

void read_text_tag(TIFF *tif, TDimTiffIFD *ifd, DIM_UINT tag, MemIOBuf *outIOBuf)
{
  uint32 buf_size;
  uint32 buf_type;  
  DIM_UCHAR *buf = NULL;
  
  if (isTagPresentInIFD ( ifd, tag ) == TRUE )
  {
    readTiffTag (tif, ifd, tag, buf_size, buf_type, &buf);
    change_0_to_n ((char *) buf, buf_size);
    MemIO_WriteProc( (thandle_t) outIOBuf, buf, buf_size );
    freeTiffTagBuf( (DIM_UCHAR **) &buf );
  }
}

char* read_text_tiff_metadata ( TDimFormatHandle *fmtHndl, TDimTiffParams *tifParams )
{
  TIFF *tif = tifParams->dimTiff;
  TDimTiffIFD *ifd = &tifParams->ifds.ifds[0];
  MemIOBuf outIOBuf;
  char *str = NULL;

  MemIO_InitBuf( &outIOBuf, 0, NULL );

  //-------------------------------------------------------------------------------
  // Some internal meta data
  //-------------------------------------------------------------------------------

  write_title_text("Internal Metadata", &outIOBuf);
  
  if (tifParams->subType == tstStk) 
    stkWriteTextMeta(tifParams, &outIOBuf);

  if (tifParams->subType == tstPsia) 
    psiaWriteTextMeta(tifParams, &outIOBuf);

  if (tifParams->subType == tstFluoview)
    fluoviewWriteTextMeta(tifParams, &outIOBuf);    

  //-------------------------------------------------------------------------------
  // Standard TIFF tags
  //-------------------------------------------------------------------------------

  //DocumentName
  read_text_tag(tif, ifd, 269, &outIOBuf, "Document Name");

  //ImageDescription
  if (tifParams->subType == tstStk)
  {
    uint32 buf_size;
    uint32 buf_type;  
  
    if (isTagPresentInIFD ( ifd, 270 ) == TRUE )
    {
      DIM_UCHAR *buf = NULL;
      write_title_text("Image Description", &outIOBuf);
      readTiffTag (tif, ifd, 270, buf_size, buf_type, (DIM_UCHAR **) &buf);
      MemIO_WriteProc( (thandle_t) &outIOBuf, buf, strlen((char *) buf)-1 );
      freeTiffTagBuf( (DIM_UCHAR **) &buf );
    }
  }
  else
  if (tifParams->subType != tstFluoview)
    read_text_tag(tif, ifd, 270, &outIOBuf, "Image Description");

  //PageName
  if (tifParams->subType != tstFluoview)
    read_text_tag(tif, ifd, 285, &outIOBuf, "Page Name");

  //Make
  read_text_tag(tif, ifd, 271, &outIOBuf, "Make");

  //Model
  read_text_tag(tif, ifd, 272, &outIOBuf, "Model");

  //Software
  read_text_tag(tif, ifd, 305, &outIOBuf, "Software");

  //DateTime
  read_text_tag(tif, ifd, 306, &outIOBuf, "Date Time");

  //Artist
  read_text_tag(tif, ifd, 315, &outIOBuf, "Artist");

  //HostComputer
  read_text_tag(tif, ifd, 316, &outIOBuf, "Host Computer");

  
  str = new char [outIOBuf.size+1];
  str[outIOBuf.size] = '\0';
  memcpy( str, outIOBuf.data, outIOBuf.size );
  
  MemIO_DeinitBuf( &outIOBuf );

  return str;
}

DIM_UINT write_tiff_metadata (TDimFormatHandle *fmtHndl, TDimTiffParams *tifParams)
{
  if (!areValidParams(fmtHndl, tifParams)) return 1;

  DIM_UINT i;
  TDimTagList *tagList = &fmtHndl->metaData;
  void  *t_list = NULL;
  int16 t_list_count;
  TIFF *tif = tifParams->dimTiff;

  if (tagList->count == 0) return 1;
  if (tagList->tags == NULL) return 1;

  for (i=0; i<tagList->count; i++)
  {
    TDimTagItem *tagItem = &tagList->tags[i];
    if (tagItem->tagGroup == DIM_META_TIFF_TAG)
    {
      t_list = tagItem->tagData;
      t_list_count = tagItem->tagLength;

      TIFFSetField( tif, tagItem->tagId, tagItem->tagLength, tagItem->tagData ); 
    }
  }

  return 0;
}


//****************************************************************************
// WRITING LINE SEGMENT FROM BUFFER
//****************************************************************************

void write_line_segment_8(void *po, void *bufo, TDimImageBitmap *img, DIM_UINT sample, DIM_ULONG w)
{
  DIM_UCHAR *p   = (DIM_UCHAR *) po;
  DIM_UCHAR *buf = (DIM_UCHAR *) bufo;  
  
  DIM_UINT nsamples = img->i.samples;
  register DIM_UINT x, xi=0;

  for (x=sample; x<w*nsamples; x+=nsamples) 
  {
    p[xi] = buf[x];
    xi++;
  }
}

void write_line_segment_16(void *po, void *bufo, TDimImageBitmap *img, DIM_UINT sample, DIM_ULONG w)
{
  DIM_UINT16 *p   = (DIM_UINT16 *) po;
  DIM_UINT16 *buf = (DIM_UINT16 *) bufo;  
  
  DIM_UINT nsamples = img->i.samples;
  register DIM_UINT x, xi=0;

  for (x=sample; x<w*nsamples; x+=nsamples) 
  {
    p[xi] = buf[x];
    xi++;
  }

⌨️ 快捷键说明

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