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

📄 tif.cpp

📁 <精通Visual C++图像处理编程>源码 对于图像处理很有帮助
💻 CPP
📖 第 1 页 / 共 2 页
字号:
          m_head.biBitCount = 4;    
          m_head.biClrUsed  = 16;
        } else {
          //
          // gray scale
          //
          m_head.biBitCount = 8;    
          m_head.biClrUsed  = 256;
        }
      } else if (bitspersample == 4) {
        //
        // 16 colors
        //
        m_head.biBitCount = 4;
        m_head.biClrUsed  = 16;
      } else {
        //
        // 256 colors
        //
        m_head.biBitCount = 8;      
        m_head.biClrUsed  = 256;
      }
    }

    //
    //  Create  the dib and bitmap.
    //
    Create( m_head.biWidth, m_head.biHeight, m_head.biBitCount );

    if (m_bIsRGB) {
      //
      // Read the whole image into one big RGBA buffer using
      // the traditional TIFFReadRGBAImage() API that we trust.
      //
      uint32 * raster;    // retrieve RGBA image
      uint32 * row;

      raster = (uint32*)_TIFFmalloc(width * height * sizeof (uint32));
      if (raster == NULL)
        return FALSE;

      //
      // Read the image in one chunk into an RGBA array
      //
      if(!TIFFReadRGBAImage( m_tif, width, height, raster, 1)) {
        _TIFFfree( raster );
        return FALSE;
      }

      //
      // read the raster lines and save them in the DIB
      // with RGB mode, we have to change the order of the 3 samples RGB
      //
      row = &raster[0];
      bits2 = m_info.pImage;
      for (y = 0; y < height; y++) {
        bits = bits2;
        for (x = 0; x < width; x++) {
          *bits++ = (BYTE)TIFFGetB( row[x] );
          *bits++ = (BYTE)TIFFGetG( row[x] );
          *bits++ = (BYTE)TIFFGetR( row[x] );
        }
        row   += width;
        bits2 += m_info.dwEffWidth;
      }
      _TIFFfree( raster );
    } else {
      RGBQUAD * pal;
      pal = (RGBQUAD*)calloc(256,sizeof(RGBQUAD));
      if (pal==NULL) 
        return FALSE;

      //
      // set up the colormap based on photometric  
      //
      switch (photometric) {
        //
        // bitmap and greyscale image types
        //
        case PHOTOMETRIC_MINISBLACK:  
        case PHOTOMETRIC_MINISWHITE:
          //
          // Monochrome image
          //
          if (bitspersample == 1) {  
            if (photometric == PHOTOMETRIC_MINISBLACK) {
              pal[ 1 ].rgbRed = pal[ 1 ].rgbGreen = pal[ 1 ].rgbBlue = 255;
            } else {
              pal[ 0 ].rgbRed = pal[ 0 ].rgbGreen = pal[ 0 ].rgbBlue = 255;
            }
          } else {    
            //
            // need to build the scale for greyscale images
            //
            if (photometric == PHOTOMETRIC_MINISBLACK) {
              for (UINT i = 0; i < m_head.biClrUsed; i++) {
                pal[ i ].rgbRed = pal[ i ].rgbGreen = pal[ i ].rgbBlue = (BYTE)(i * (255 / (m_head.biClrUsed - 1 )));
              }
            } else {
              for (UINT i = 0; i < m_head.biClrUsed; i++) {
                pal[ i ].rgbRed = pal[ i ].rgbGreen = pal[ i ].rgbBlue = (BYTE)(255 - i * (255 / (m_head.biClrUsed - 1)));
              }
            }
          }
          break;
        case PHOTOMETRIC_PALETTE:  // color map indexed
          uint16 * red;
          uint16 * green;
          uint16 * blue;
          TIFFGetField( m_tif, TIFFTAG_COLORMAP, &red, &green, &blue ); 

          //
          // Is the palette 16 or 8 bits ?
          //
          BOOL Palette16Bits = FALSE;
          int n = 1 << bitspersample;
          while (n-- > 0) {
            if (red[ n ] >= 256 || green[ n ] >= 256 || blue[n] >= 256) {
              Palette16Bits=TRUE;
              break;
            }
          }

          //
          // load the palette in the DIB
          //
          for (int i = (1 << bitspersample) - 1; i >= 0; i--) {
            if (Palette16Bits) {
              pal[ i ].rgbRed   = (BYTE)CVT(red[ i ]);
              pal[ i ].rgbGreen = (BYTE)CVT(green[ i ]);
              pal[ i ].rgbBlue  = (BYTE)CVT(blue[ i ]);           
            } else {
              pal[ i ].rgbRed   = (BYTE)red[ i ];
              pal[ i ].rgbGreen = (BYTE)green[ i ];
              pal[ i ].rgbBlue  = (BYTE)blue[ i ];        
            }
          }
          break;
      }

      //
      // Set the pallet up.
      //
	    if ( (pal != NULL)
                 &&
           (m_pDib != NULL)
                 &&
           (m_head.biClrUsed != 0))
      {
	      memcpy( (RGBQUAD*)((BYTE*)m_pDib + sizeof(BITMAPINFOHEADER)),pal,min( (m_head.biClrUsed * sizeof(RGBQUAD)), m_head.biClrUsed * sizeof( RGBQUAD ) ) );
      } 
      free( pal );


      //
      // read the tiff lines and save them in the DIB
      //
      uint32 nrow;
      uint32 ys;
      int  line    = CalculateLine(width, bitspersample * samplesperpixel);
      long bitsize = TIFFStripSize( m_tif );

      //
      // verify bitsize: could be wrong if StripByteCounts is missing.
      //
      if ( bitsize > (long)(m_info.dwEffWidth * height) )
        bitsize = m_info.dwEffWidth * height;

      bits = (BYTE*)malloc( bitsize );

      for (ys = 0; ys < height; ys += rowsperstrip) {
        nrow = (ys + rowsperstrip > height ? height - ys : rowsperstrip);
        if (TIFFReadEncodedStrip( m_tif, TIFFComputeStrip( m_tif, ys, 0 ), bits, nrow * line ) == -1) {
          free( bits );
          return 0;
        }

        for (y = 0; y < nrow; y++)  {
          long offset = (nrow-y-1) * line;
          if (bitspersample == 16) {
            for (ULONG xi = 0; xi < width; xi++)
              bits[ xi + offset ] = bits[ xi * 2 + offset + 1 ];
          }
          memcpy( m_info.pImage + m_info.dwEffWidth * (height - ys - nrow + y),bits + offset,m_info.dwEffWidth );
        }
      }

      free( bits );
    }
  } catch(...) {
    return FALSE;
  }

  return TRUE;
}


void * CTif::Create( DWORD a_dwWidth, DWORD a_dwHeight, long a_wBpp )
{
  //
  // destroy the existing image (if any)
  //
  if (m_pDib)
    free( m_pDib );

  m_pDib = NULL;

  //
  // Make sure bits per pixel is valid
  //
  if (a_wBpp <= 1)
    a_wBpp = 1;
  else if (a_wBpp <= 4)
    a_wBpp = 4;
  else if (a_wBpp <= 8)
    a_wBpp = 8;
  else
    a_wBpp = 24;

  //
  // set the correct bpp value
  //
  switch (a_wBpp) {
    case 1:
        m_head.biClrUsed = 2;
        break;
    case 4:
        m_head.biClrUsed = 16;
        break;
    case 8:
        m_head.biClrUsed = 256;
        break;
    default:
        m_head.biClrUsed = 0;
  }

  //
  //set the common image informations
  //
  m_info.bColorType = (BYTE)((a_wBpp >8) ? COLORTYPE_COLOR : COLORTYPE_PALETTE);
  m_info.dwEffWidth = ( ( ( (a_wBpp * a_dwWidth) + 31) / 32) * 4);

  //
  // initialize BITMAPINFOHEADER
  //
  m_head.biWidth         = a_dwWidth;      // fill in width from parameter
  m_head.biHeight        = a_dwHeight;     // fill in height from parameter
  m_head.biPlanes        = 1;              // must be 1
  m_head.biBitCount      = (WORD)a_wBpp;   // from parameter
  m_head.biCompression   = BI_RGB;    
  m_head.biSizeImage     = m_info.dwEffWidth * a_dwHeight;
  m_head.biXPelsPerMeter = (long) floor(m_info.xDPI * 10000.0 / 254.0 + 0.5);
  m_head.biYPelsPerMeter = (long) floor(m_info.yDPI * 10000.0 / 254.0 + 0.5);
  m_head.biClrImportant  = 0;

  //
  // alloc memory block to store our bitmap
  //
  long lDibSize = m_head.biSize + m_head.biSizeImage + (m_head.biClrUsed * sizeof(RGBQUAD));
  m_pDib = malloc( lDibSize ); 
  if (!m_pDib)
    return NULL;
  
  //
  // clear the palette
  //
  RGBQUAD * pal = NULL;
  if ((m_pDib) && (m_head.biClrUsed))
    pal = (RGBQUAD*)((BYTE*)m_pDib + sizeof(BITMAPINFOHEADER));

  if (pal) 
    memset( pal,0,(m_head.biClrUsed * sizeof(RGBQUAD)) );

  //
  // use our bitmap info structure to fill in first part of
  // our DIB with the BITMAPINFOHEADER
  //
  LPBITMAPINFOHEADER  lpbi;
  lpbi  = (LPBITMAPINFOHEADER)(m_pDib);
  *lpbi = m_head;
  m_info.pImage = ((BYTE*)m_pDib + *(LPDWORD)m_pDib + (m_head.biClrUsed * sizeof(RGBQUAD)));


  return m_pDib; //return handle to the DIB
}

void CTif::SetPaletteIndex(BYTE idx, BYTE r, BYTE g, BYTE b, BYTE alpha)
{
	if ((m_pDib) && (m_head.biClrUsed)) {
		BYTE * iDst = (BYTE*)(m_pDib) + sizeof(BITMAPINFOHEADER);
		if (idx < m_head.biClrUsed) {
			long ldx = idx * sizeof( RGBQUAD );
			iDst[ ldx++ ] = (BYTE)b;
			iDst[ ldx++ ] = (BYTE)g;
			iDst[ ldx++ ] = (BYTE)r;
			iDst[ ldx ]   = (BYTE)alpha;
		}
	}
}

int CTif::FillColorMap( QT_COLOR_MAP * colors )
{
  
  long count_colors = 1 << bitspersample;
  int i;
  switch (photometric) {
    case PHOTOMETRIC_MINISBLACK:
    {
      for ( i = 0; i < (long) count_colors; i++) {
        colors[ i ].red   = (((double) 255 * i)/max(count_colors - 1,1)+0.5);
        colors[ i ].green = colors[ i ].red;
        colors[ i ].blue  = colors[ i ].red;
      }
      break;
    }
    case PHOTOMETRIC_MINISWHITE:
    default:
    {
      for (i=0; i < (long) count_colors; i++) {
        colors[ i ].red   =(255- (((double) 255 * i) / max( count_colors - 1,1))+0.5);
        colors[ i ].green = colors[ i ].red;
        colors[ i ].blue  = colors[ i ].red;
      }
      break;
    }
    case PHOTOMETRIC_PALETTE:
    {
      long range;

      uint16 * blue_colormap, *green_colormap, *red_colormap;

      TIFFGetField(m_tif,TIFFTAG_COLORMAP,&red_colormap, &green_colormap,&blue_colormap); 
      range=256L;  /* might be old style 8-bit colormap */
      for (i=0; i < (long) count_colors; i++)
        if ((red_colormap[i] >= 256) || (green_colormap[i] >= 256) || (blue_colormap[i] >= 256)) 
        {
            range=65535L;
            break;
        }

      for (i=0; i < (long) count_colors; i++) {
        colors[ i ].red   = (((double) 255 * red_colormap[ i ])   / range+0.5);
        colors[ i ].green = (((double) 255 * green_colormap[ i ]) / range+0.5);
        colors[ i ].blue  = (((double) 255 * blue_colormap[ i ])  / range+0.5);
      }
      break;
    }
  }

  return 1;
}

⌨️ 快捷键说明

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