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

📄 dim_tiff_format_io.cpp

📁 Digital Notebook Source Code v1.1.0 [
💻 CPP
📖 第 1 页 / 共 2 页
字号:
}

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 + -