📄 tif.cpp
字号:
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 + -