コード例 #1
0
void CurveLines::Init( class NavDebugDraw* drawtool )
{
	Draw_ = drawtool;
	Index_ = 0;
	m_NumVerts = 0; //MAX_DRAWLINE;
	AddPoint(vec3_zero);

	CalculateLine();
}
コード例 #2
0
ファイル: TestDlg.cpp プロジェクト: Nillouise/WinRobot
LRESULT CTestDlg::OnBnClickedButton5(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	bool bRtn = true;

	HANDLE hf = INVALID_HANDLE_VALUE;
	HANDLE hf2 = INVALID_HANDLE_VALUE;
	try
	{
		hf = CreateFile(_T("E:\\DumpSurface2.temp"), 
			GENERIC_READ , 
			(DWORD) 0, 
			NULL, 
			OPEN_EXISTING, 
			FILE_ATTRIBUTE_NORMAL, 
			(HANDLE) NULL); 

		if (hf == INVALID_HANDLE_VALUE) 
		{ 
			throw FALSE;
		}
		DDSURFACEDESC2 ddsd;
		DWORD cbRead = 0;
		ReadFile(hf,&ddsd,sizeof(ddsd),&cbRead,0);
		CFileMappingBitmap file;
		file.Create(ddsd.dwWidth,ddsd.dwHeight,ddsd.ddpfPixelFormat.dwRGBBitCount,0,0,_T("1268-1-74EF6127C-0846-4c63-8EAE-6C2DF379A618"));
		
		BYTE*pPointer = (BYTE*)file.GetImagePointer();
		
		int pitch = CalculatePitch(CalculateLine(ddsd.dwWidth,ddsd.ddpfPixelFormat.dwRGBBitCount));
		while ( ReadFile(hf,pPointer,pitch,&cbRead,0) )
		{
			SetFilePointer(hf,ddsd.lPitch - pitch,0,FILE_CURRENT );
			pPointer += pitch;
		}
		
		hf2 = CreateFile(_T("E:\\DumpSurface2.bmp"), 
			GENERIC_READ | GENERIC_WRITE, 
			(DWORD) 0, 
			NULL, 
			CREATE_ALWAYS, 
			FILE_ATTRIBUTE_NORMAL, 
			(HANDLE) NULL); 

		WriteFile(hf2,file.GetFilePointer(),file.GetFileSize(),&cbRead,0);

		
	}
	catch(bool b1)
	{
		bRtn = b1;
	}
	CloseHandle(hf);
	CloseHandle(hf2);
	return 0;
}
コード例 #3
0
/**
Calculate the size of a FreeImage image. 
Align the palette and the pixels on a FIBITMAP_ALIGNMENT bytes alignment boundary.
*/
static unsigned 
FreeImage_GetImageSize(int width, int height, int bpp) {
	unsigned dib_size = sizeof(FREEIMAGEHEADER); 
	dib_size += (dib_size % FIBITMAP_ALIGNMENT ? FIBITMAP_ALIGNMENT - dib_size % FIBITMAP_ALIGNMENT : 0);  
	dib_size += FIBITMAP_ALIGNMENT - sizeof(BITMAPINFOHEADER) % FIBITMAP_ALIGNMENT; 
	dib_size += sizeof(BITMAPINFOHEADER);  
	// palette is aligned on a 16 bytes boundary
	dib_size += sizeof(RGBQUAD) * CalculateUsedPaletteEntries(bpp);  
	dib_size += (dib_size % FIBITMAP_ALIGNMENT ? FIBITMAP_ALIGNMENT - dib_size % FIBITMAP_ALIGNMENT : 0);  
	// pixels are aligned on a 16 bytes boundary
	dib_size += CalculatePitch(CalculateLine(width, bpp)) * height; 

	return dib_size;
}
コード例 #4
0
ファイル: BitmapAccess.cpp プロジェクト: FlyApple/_3rdParty
/**
Calculate the size of a FreeImage image. 
Align the palette and the pixels on a FIBITMAP_ALIGNMENT bytes alignment boundary.
This function includes a protection against malicious images, based on a KISS integer overflow detection mechanism. 

@param header_only If TRUE, calculate a 'header only' FIBITMAP size, otherwise calculate a full FIBITMAP size
@param width Image width
@param height Image height
@param bpp Number of bits-per-pixel
@param need_masks We only store the masks (and allocate memory for them) for 16-bit images of type FIT_BITMAP
@return Returns a size in BYTE units
@see FreeImage_AllocateBitmap
*/
static size_t 
FreeImage_GetInternalImageSize(BOOL header_only, unsigned width, unsigned height, unsigned bpp, BOOL need_masks) {
	size_t dib_size = sizeof(FREEIMAGEHEADER);
	dib_size += (dib_size % FIBITMAP_ALIGNMENT ? FIBITMAP_ALIGNMENT - dib_size % FIBITMAP_ALIGNMENT : 0);
	dib_size += FIBITMAP_ALIGNMENT - sizeof(BITMAPINFOHEADER) % FIBITMAP_ALIGNMENT;
	dib_size += sizeof(BITMAPINFOHEADER);
	// palette is aligned on a 16 bytes boundary
	dib_size += sizeof(RGBQUAD) * CalculateUsedPaletteEntries(bpp);
	// we both add palette size and masks size if need_masks is true, since CalculateUsedPaletteEntries
	// always returns 0 if need_masks is true (which is only true for 16 bit images).
	dib_size += need_masks ? sizeof(DWORD) * 3 : 0;
	dib_size += (dib_size % FIBITMAP_ALIGNMENT ? FIBITMAP_ALIGNMENT - dib_size % FIBITMAP_ALIGNMENT : 0);

	if(!header_only) {
		const size_t header_size = dib_size;

		// pixels are aligned on a 16 bytes boundary
		dib_size += (size_t)CalculatePitch(CalculateLine(width, bpp)) * (size_t)height;

		// check for possible malloc overflow using a KISS integer overflow detection mechanism
		{
			const double dPitch = floor( ((double)bpp * width + 31.0) / 32.0 ) * 4.0;
			const double dImageSize = (double)header_size + dPitch * height;
			if(dImageSize != (double)dib_size) {
				// here, we are sure to encounter a malloc overflow: try to avoid it ...
				return 0;
			}

			/*
			The following constant take into account the additionnal memory used by 
			aligned malloc functions as well as debug malloc functions. 
			It is supposed here that using a (8 * FIBITMAP_ALIGNMENT) risk margin will be enough
			for the target compiler. 
			*/
			const double FIBITMAP_MAX_MEMORY = (double)((size_t)-1) - 8 * FIBITMAP_ALIGNMENT;

			if(dImageSize > FIBITMAP_MAX_MEMORY) {
				// avoid possible overflow inside C allocation functions
				return 0;
			}
		}
	}

	return dib_size;
}
コード例 #5
0
ファイル: ScreenBuffer.cpp プロジェクト: Nillouise/WinRobot
bool CScreenBuffer::Create(HDC hDev,const RECT & rc,LPCTSTR szName )
{
	TrackDebugOut;
	Destroy();
	m_hMemDC = CreateCompatibleDC(hDev);
	if(m_hMemDC == NULL){
		DebugOutF(filelog::log_error,("CreateCompatibleDC failed with %d"),GetLastError() );
		return false;
	}
	RECT rcscreen = GetDCRect(hDev);
	RECT rcdest;
	IntersectRect(&rcdest,&rcscreen,&rc);

	LONG lWidth		= rcdest.right - rcdest.left;
	LONG lHeight	= rcdest.bottom - rcdest.top; 
	LONG lBitsPPix	= 32;//GetDeviceCaps(hDev,BITSPIXEL);
	LONG dwImageSize = lHeight*CalculatePitch(CalculateLine(lWidth,lBitsPPix));


	// save [bmp file header] + [bmp info header] + [bmp data] to the file mapping object
	//DWORD filesize = 0;
	LONG biClrUsed = 0;
	RGBQUAD rgbquad[256];
	if (lBitsPPix < 16)
	{
		TrackDebugOut;
		biClrUsed = GetDIBColorTable(hDev,0,256,rgbquad);
	}
	
	if(!CFileMappingBitmap::Create(lWidth,lHeight,lBitsPPix,biClrUsed,rgbquad,szName))
	{
		return false;
	}
	
	m_hBmp = CreateDIBSection(m_hMemDC,(BITMAPINFO*)InfoHeader(),DIB_RGB_COLORS, (void**)&m_pBuff, GetHandle(), FileHeader()->bfOffBits);
	if(m_hBmp == NULL){
		DebugOutF(filelog::log_error,("CreateDIBSection failed %d"),GetLastError() );
		return false;
	}
	SelectObject(m_hMemDC,m_hBmp);
	//HDC hdc = GetDC(0);
	BitBlt(m_hMemDC,0,0,rcdest.right-rcdest.left,rcdest.bottom-rcdest.top,hDev,rcdest.left,rcdest.top,SRCCOPY|CAPTUREBLT);
	//ReleaseDC(0,hdc);
	return true;
}
コード例 #6
0
ファイル: imatiff.cpp プロジェクト: wermanhme1990/xcommon
BOOL CImageTIFF::Read(FILE* stream)
{
	TIFF* m_tif = TIFFOpenEx(stream, "rb");

	uint32 height=0;
	uint32 width=0;
	uint16 bitspersample=1;
	uint16 samplesperpixel=1;
	uint32 rowsperstrip=-1;
	uint16 photometric=0;
	uint16 compression=1;
	uint32 x, y;
	BOOL isRGB;
	BYTE *bits;		//pointer to source data
	BYTE *bits2;	//pointer to destination data

  try{
	//check if it's a tiff file
	if (!m_tif)
		throw "Error encountered while opening TIFF file";

	m_info.nNumFrames=0;
	while(TIFFSetDirectory(m_tif,(uint16)m_info.nNumFrames)) m_info.nNumFrames++;


	if (!TIFFSetDirectory(m_tif, (uint16)m_info.nFrame))
		throw "Error: page not present in TIFF file";			

	//get image m_info
	TIFFGetField(m_tif, TIFFTAG_COMPRESSION, &compression);
	if (compression == COMPRESSION_LZW)
		throw "LZW compression is no longer supported due to Unisys patent enforcement";			

	TIFFGetField(m_tif, TIFFTAG_IMAGEWIDTH, &width);
	TIFFGetField(m_tif, TIFFTAG_IMAGELENGTH, &height);
	TIFFGetField(m_tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
	TIFFGetField(m_tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
	TIFFGetField(m_tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);   
	TIFFGetField(m_tif, TIFFTAG_PHOTOMETRIC, &photometric);

	m_header.biWidth  = width;
	m_header.biHeight = height;
	m_header.biClrUsed=0;
	m_info.nBkgndIndex =-1;

	isRGB = (bitspersample >= 8) &&
		(photometric == PHOTOMETRIC_RGB) ||
		(photometric == PHOTOMETRIC_YCBCR) ||
		(photometric == PHOTOMETRIC_SEPARATED) ||
		(photometric == PHOTOMETRIC_LOGLUV);

	if (isRGB){
		m_header.biBitCount=24;
		m_info.bColorType = COLORTYPE_COLOR;
	}else{
		m_info.bColorType = COLORTYPE_PALETTE;
		if ((photometric==PHOTOMETRIC_MINISBLACK)||(photometric==PHOTOMETRIC_MINISWHITE)){
			if	(bitspersample == 1){
				m_header.biBitCount=1;		//B&W image
				m_header.biClrUsed =2;
			} else {
				m_header.biBitCount=8;		//gray scale
				m_header.biClrUsed =256;
			}
		} else if (bitspersample == 4) {
			m_header.biBitCount=4;			// 16 colors
			m_header.biClrUsed=16;
		} else {
			m_header.biBitCount=8;			//256 colors
			m_header.biClrUsed=256;
		}
	}

	Create(m_header.biWidth,m_header.biHeight,m_header.biBitCount);	//image creation

	if (isRGB) {
		// 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) throw "No space for raster buffer";
			
		// Read the image in one chunk into an RGBA array
		if(!TIFFReadRGBAImage(m_tif, width, height, raster, 1)) {
				_TIFFfree(raster);
				throw "Corrupted TIFF file!";
		}

		// 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) throw "Unable to allocate TIFF palette";

		// set up the colormap based on photometric	
		switch(photometric) {
			case PHOTOMETRIC_MINISBLACK:	// bitmap and greyscale image types
			case PHOTOMETRIC_MINISWHITE:
				if (bitspersample == 1) {	// Monochrome image
					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 (int i = 0; i < 256; i++) {
							pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = i;
						}
					} else {
						for (int i = 0; i < 256; i++) {
							pal[i].rgbRed =	pal[i].rgbGreen = pal[i].rgbBlue = 255 - i;
						}
					}
				}
				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;
		}
		SetPalette(pal,m_header.biClrUsed);	//palette assign
		free(pal);

		// read the tiff lines and save them in the DIB
		uint32 nrow;
		uint32 ys;
		int line = CalculateLine(width, bitspersample * samplesperpixel);
//		int pitch = CalculatePitch(line);
		long bitsize= TIFFStripSize(m_tif);
		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);
				throw "Corrupted TIFF file!";
			}
			for (y = 0; y < nrow; y++) {
				memcpy(m_info.pImage+m_info.dwEffWidth*(height-ys-nrow+y),bits+(nrow-y-1)*line,line);
			}
			/*if (m_header.biClrUsed==2){
				for (y = 0; y < nrow; y++) { for (x = 0; x < width; x++) {
					SetPixelIndex(x,y+ys,(bits[y*line+(x>>3)]>>(7-x%8))&0x01);
			}}}*/
		}
		free(bits);
	}
  } catch (char *message) {
	  strncpy(m_info.szLastError,message,255);
	  if (m_tif)	TIFFClose(m_tif);
	  return FALSE;
  }
	TIFFClose(m_tif);
	return TRUE;
}
コード例 #7
0
ファイル: imatiff.cpp プロジェクト: wermanhme1990/xcommon
BOOL CImageTIFF::Write(FILE* stream)
{
	//prepare the palette struct
	RGBQUAD pal[256];
	if (GetPalette()){
		BYTE b;
		memcpy(pal,GetPalette(),GetPaletteSize());
		for(WORD a=0;a<m_header.biClrUsed;a++){	//swap blue and red components
			b=pal[a].rgbBlue; pal[a].rgbBlue=pal[a].rgbRed; pal[a].rgbRed=b;
		}
	}
	
	TIFF *m_tif=NULL; // = (TIFF *)new(byte[512]);

	uint32 height=m_header.biHeight;
	uint32 width=m_header.biWidth;
//	uint32 rowsperstrip = (uint32) -1;
	uint16 bitspersample=m_header.biBitCount;
	uint16 samplesperpixel;
	uint16 photometric;
	uint16 compression;
	uint16 pitch;
	int line;
	uint32 x, y;

	samplesperpixel = ((bitspersample == 24) || (bitspersample == 32)) ? 3 : 1;
	photometric = (samplesperpixel==3) ? PHOTOMETRIC_RGB : PHOTOMETRIC_PALETTE;
	line = CalculateLine(width, bitspersample * samplesperpixel);
	pitch = CalculatePitch(line);

	m_tif=TIFFOpenEx(stream, "wb");
	if (m_tif==NULL) return FALSE;

	// handle standard width/height/bpp stuff
	TIFFSetField(m_tif, TIFFTAG_IMAGEWIDTH, width);
	TIFFSetField(m_tif, TIFFTAG_IMAGELENGTH, height);
	TIFFSetField(m_tif, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
	TIFFSetField(m_tif, TIFFTAG_BITSPERSAMPLE, ((bitspersample == 32) ? 24 : bitspersample) / samplesperpixel);
	TIFFSetField(m_tif, TIFFTAG_PHOTOMETRIC, photometric);
	TIFFSetField(m_tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);	// single image plane 
	TIFFSetField(m_tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
	TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, 1);
//	TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(m_tif, rowsperstrip));

	// handle metrics
	TIFFSetField(m_tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
	TIFFSetField(m_tif, TIFFTAG_XRESOLUTION, 72.0);
	TIFFSetField(m_tif, TIFFTAG_YRESOLUTION, 72.0);

	// multi-paging
//	if (page >= 0) {
//		char page_number[20];
//		sprintf(page_number, "Page %d", page);
//
//		TIFFSetField(m_tif, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
//		TIFFSetField(m_tif, TIFFTAG_PAGENUMBER, page);
//		TIFFSetField(m_tif, TIFFTAG_PAGENAME, page_number);
//	} else {
		TIFFSetField(m_tif, TIFFTAG_SUBFILETYPE, 0);
//	}

	// palettes (image colormaps are automatically scaled to 16-bits)
	if (photometric == PHOTOMETRIC_PALETTE) {
		uint16 *r, *g, *b;
		r = (uint16 *) _TIFFmalloc(sizeof(uint16) * 3 * 256);
		g = r + 256;
		b = g + 256;

		for (int i = 255; i >= 0; i--) {
			b[i] = SCALE((uint16)pal[i].rgbRed);
			g[i] = SCALE((uint16)pal[i].rgbGreen);
			r[i] = SCALE((uint16)pal[i].rgbBlue);
		}

		TIFFSetField(m_tif, TIFFTAG_COLORMAP, r, g, b);
		_TIFFfree(r);
	}

	// compression
	switch(bitspersample) {
		case 1 :
			compression = COMPRESSION_CCITTFAX4;
			break;
		case 8 :
		case 24 :
		case 32 :
			compression = COMPRESSION_PACKBITS;
			break;
		default :
			compression = COMPRESSION_NONE;
			break;
	}
	TIFFSetField(m_tif, TIFFTAG_COMPRESSION, compression);

	// read the DIB lines from bottom to top
	// and save them in the TIF
	// -------------------------------------	
	BYTE *bits;
	switch(bitspersample) {				
		case 1 :
		case 4 :
		case 8 :
		{
			for (y = 0; y < height; y++) {
				bits= m_info.pImage + (height - y - 1)*m_info.dwEffWidth;
				TIFFWriteScanline(m_tif,bits, y, 0);
			}
			break;
		}				
		case 24:
		case 32 :
		{
			BYTE *buffer = (BYTE *)malloc(m_info.dwEffWidth);
			for (y = 0; y < height; y++) {
				// get a pointer to the scanline
				memcpy(buffer, m_info.pImage + (height - y - 1)*m_info.dwEffWidth, m_info.dwEffWidth);
				// TIFFs store color data RGB instead of BGR
				BYTE *pBuf = buffer;
				for (x = 0; x < width; x++) {
					BYTE tmp = pBuf[0];
					pBuf[0] = pBuf[2];
					pBuf[2] = tmp;
					pBuf += 3;
				}
				// write the scanline to disc
				TIFFWriteScanline(m_tif, buffer, y, 0);
			}
			free(buffer);
			break;
		}				
	}
	TIFFClose(m_tif);
	return true;
}
コード例 #8
0
ファイル: PluginBMP.cpp プロジェクト: MichaelH13/sdkpub
static FIBITMAP *
LoadOS21XBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bits_offset) {
	FIBITMAP *dib = NULL;

	try {
		BITMAPINFOOS2_1X_HEADER bios2_1x;

		io->read_proc(&bios2_1x, sizeof(BITMAPINFOOS2_1X_HEADER), 1, handle);
#ifdef FREEIMAGE_BIGENDIAN
		SwapOS21XHeader(&bios2_1x);
#endif
		// keep some general information about the bitmap

		int used_colors = 0;
		int width       = bios2_1x.biWidth;
		int height      = bios2_1x.biHeight;
		int bit_count   = bios2_1x.biBitCount;
		int pitch       = CalculatePitch(CalculateLine(width, bit_count));
		
		switch (bit_count) {
			case 1 :
			case 4 :
			case 8 :
			{
				used_colors = CalculateUsedPaletteEntries(bit_count);
				
				// allocate enough memory to hold the bitmap (header, palette, pixels) and read the palette

				dib = FreeImage_Allocate(width, height, bit_count);

				if (dib == NULL)
					throw "DIB allocation failed";						

				BITMAPINFOHEADER *pInfoHeader = FreeImage_GetInfoHeader(dib);
				pInfoHeader->biXPelsPerMeter = 0;
				pInfoHeader->biYPelsPerMeter = 0;
				
				// load the palette

				RGBQUAD *pal = FreeImage_GetPalette(dib);

				for (int count = 0; count < used_colors; count++) {
					FILE_BGR bgr;

					io->read_proc(&bgr, sizeof(FILE_BGR), 1, handle);
					
					pal[count].rgbRed = bgr.r;
					pal[count].rgbGreen = bgr.g;
					pal[count].rgbBlue = bgr.b;
				}

				// Skip over the optional palette 
				// A 24 or 32 bit DIB may contain a palette for faster color reduction

				io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
				
				// read the pixel data

				if (height > 0) {
					io->read_proc((void *)FreeImage_GetBits(dib), height * pitch, 1, handle);
				} else {
					for (int c = 0; c < abs(height); ++c) {
						io->read_proc((void *)FreeImage_GetScanLine(dib, height - c - 1), pitch, 1, handle);								
					}
				}
						
				return dib;
			}

			case 16 :
			{
				dib = FreeImage_Allocate(width, height, bit_count, FI16_555_RED_MASK, FI16_555_GREEN_MASK, FI16_555_BLUE_MASK);

				if (dib == NULL)
					throw "DIB allocation failed";						

				BITMAPINFOHEADER *pInfoHeader = FreeImage_GetInfoHeader(dib);
				pInfoHeader->biXPelsPerMeter = 0;
				pInfoHeader->biYPelsPerMeter = 0;

				io->read_proc(FreeImage_GetBits(dib), height * pitch, 1, handle);
#ifdef FREEIMAGE_BIGENDIAN
				for(int y = 0; y < FreeImage_GetHeight(dib); y++) {
					WORD *pixel = (WORD *)FreeImage_GetScanLine(dib, y);
					for(int x = 0; x < FreeImage_GetWidth(dib); x++) {
						SwapShort(pixel);
						pixel++;
					}
				}
#endif

				return dib;
			}

			case 24 :
			case 32 :
			{
				if( bit_count == 32 ) {
					dib = FreeImage_Allocate(width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
				} else {
					dib = FreeImage_Allocate(width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
				}

				if (dib == NULL)
					throw "DIB allocation failed";						

				BITMAPINFOHEADER *pInfoHeader = FreeImage_GetInfoHeader(dib);
				pInfoHeader->biXPelsPerMeter = 0;
				pInfoHeader->biYPelsPerMeter = 0;

				// Skip over the optional palette 
				// A 24 or 32 bit DIB may contain a palette for faster color reduction

				io->read_proc(FreeImage_GetBits(dib), height * pitch, 1, handle);
#ifdef FREEIMAGE_BIGENDIAN
				for(int y = 0; y < FreeImage_GetHeight(dib); y++) {
					BYTE *pixel = FreeImage_GetScanLine(dib, y);
					for(int x = 0; x < FreeImage_GetWidth(dib); x++) {
						INPLACESWAP(pixel[0], pixel[2]);
						pixel += (bit_count>>3);
					}
				}
#endif

				// check if the bitmap contains transparency, if so enable it in the header

				FreeImage_SetTransparent(dib, (FreeImage_GetColorType(dib) == FIC_RGBALPHA));

				return dib;
			}
		}
	} catch(const char *message) {	
		if(dib)
			FreeImage_Unload(dib);

		FreeImage_OutputMessageProc(s_format_id, message);
	}

	return NULL;
}
コード例 #9
0
ファイル: PluginBMP.cpp プロジェクト: MichaelH13/sdkpub
static FIBITMAP *
LoadOS22XBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bits_offset) {
	FIBITMAP *dib = NULL;

	try {
		// load the info header

		BITMAPINFOHEADER bih;

		io->read_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle);
#ifdef FREEIMAGE_BIGENDIAN
		SwapInfoHeader(&bih);
#endif

		// keep some general information about the bitmap

		int used_colors = bih.biClrUsed;
		int width       = bih.biWidth;
		int height      = bih.biHeight;
		int bit_count   = bih.biBitCount;
		int compression = bih.biCompression;
		int pitch       = CalculatePitch(CalculateLine(width, bit_count));
		
		switch (bit_count) {
			case 1 :
			case 4 :
			case 8 :
			{
				if ((used_colors <= 0) || (used_colors > CalculateUsedPaletteEntries(bit_count)))
					used_colors = CalculateUsedPaletteEntries(bit_count);
					
				// allocate enough memory to hold the bitmap (header, palette, pixels) and read the palette

				dib = FreeImage_Allocate(width, height, bit_count);

				if (dib == NULL)
					throw "DIB allocation failed";

				BITMAPINFOHEADER *pInfoHeader = FreeImage_GetInfoHeader(dib);
				pInfoHeader->biXPelsPerMeter = bih.biXPelsPerMeter;
				pInfoHeader->biYPelsPerMeter = bih.biYPelsPerMeter;
				
				// load the palette

				io->seek_proc(handle, sizeof(BITMAPFILEHEADER) + bih.biSize, SEEK_SET);

				RGBQUAD *pal = FreeImage_GetPalette(dib);

				for (int count = 0; count < used_colors; count++) {
					FILE_BGR bgr;

					io->read_proc(&bgr, sizeof(FILE_BGR), 1, handle);
					
					pal[count].rgbRed = bgr.r;
					pal[count].rgbGreen = bgr.g;
					pal[count].rgbBlue = bgr.b;
				}

				// seek to the actual pixel data.
				// this is needed because sometimes the palette is larger than the entries it contains predicts

				if (bitmap_bits_offset > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * 3)))
					io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);

				// read the pixel data

				switch (compression) {
					case BI_RGB :
						if (height > 0) {
							io->read_proc((void *)FreeImage_GetBits(dib), height * pitch, 1, handle);
						} else {
							for (int c = 0; c < abs(height); ++c) {
								io->read_proc((void *)FreeImage_GetScanLine(dib, height - c - 1), pitch, 1, handle);								
							}
						}
						
						return dib;

					case BI_RLE4 :
					{
						BYTE status_byte = 0;
						BYTE second_byte = 0;
						int scanline = 0;
						int bits = 0;
						BOOL low_nibble = FALSE;

						for (;;) {
							io->read_proc(&status_byte, sizeof(BYTE), 1, handle);

							switch (status_byte) {
								case RLE_COMMAND :
									io->read_proc(&status_byte, sizeof(BYTE), 1, handle);

									switch (status_byte) {
										case RLE_ENDOFLINE :
											bits = 0;
											scanline++;
											low_nibble = FALSE;
											break;

										case RLE_ENDOFBITMAP :
											return (FIBITMAP *)dib;

										case RLE_DELTA :
										{
											// read the delta values

											BYTE delta_x;
											BYTE delta_y;

											io->read_proc(&delta_x, sizeof(BYTE), 1, handle);
											io->read_proc(&delta_y, sizeof(BYTE), 1, handle);

											// apply them

											bits       += delta_x / 2;
											scanline   += delta_y;
											break;
										}

										default :
											io->read_proc(&second_byte, sizeof(BYTE), 1, handle);

											BYTE *sline = FreeImage_GetScanLine(dib, scanline);

											for (int i = 0; i < status_byte; i++) {
												if (low_nibble) {
													*(sline + bits) |= LOWNIBBLE(second_byte);

													if (i != status_byte - 1)
														io->read_proc(&second_byte, sizeof(BYTE), 1, handle);

													bits++;
												} else {
													*(sline + bits) |= HINIBBLE(second_byte);
												}
												
												low_nibble = !low_nibble;
											}

											if (((status_byte / 2) & 1 ) == 1)
												io->read_proc(&second_byte, sizeof(BYTE), 1, handle);												

											break;
									};

									break;

								default :
								{
									BYTE *sline = FreeImage_GetScanLine(dib, scanline);

									io->read_proc(&second_byte, sizeof(BYTE), 1, handle);

									for (unsigned i = 0; i < status_byte; i++) {
										if (low_nibble) {
											*(sline + bits) |= LOWNIBBLE(second_byte);

											bits++;
										} else {
											*(sline + bits) |= HINIBBLE(second_byte);
										}				
										
										low_nibble = !low_nibble;
									}
								}

								break;
							};
						}

						break;
					}

					case BI_RLE8 :
					{
						BYTE status_byte = 0;
						BYTE second_byte = 0;
						int scanline = 0;
						int bits = 0;

						for (;;) {
							io->read_proc(&status_byte, sizeof(BYTE), 1, handle);

							switch (status_byte) {
								case RLE_COMMAND :
									io->read_proc(&status_byte, sizeof(BYTE), 1, handle);

									switch (status_byte) {
										case RLE_ENDOFLINE :
											bits = 0;
											scanline++;
											break;

										case RLE_ENDOFBITMAP :
											return (FIBITMAP *)dib;

										case RLE_DELTA :
										{
											// read the delta values

											BYTE delta_x;
											BYTE delta_y;

											io->read_proc(&delta_x, sizeof(BYTE), 1, handle);
											io->read_proc(&delta_y, sizeof(BYTE), 1, handle);

											// apply them

											bits     += delta_x;
											scanline += delta_y;
											break;
										}

										default :
											io->read_proc((void *)(FreeImage_GetScanLine(dib, scanline) + bits), sizeof(BYTE) * status_byte, 1, handle);
											
											// align run length to even number of bytes 

											if ((status_byte & 1) == 1)
												io->read_proc(&second_byte, sizeof(BYTE), 1, handle);												

											bits += status_byte;

											break;								
									};

									break;

								default :
									BYTE *sline = FreeImage_GetScanLine(dib, scanline);

									io->read_proc(&second_byte, sizeof(BYTE), 1, handle);

									for (unsigned i = 0; i < status_byte; i++) {
										*(sline + bits) = second_byte;

										bits++;
									}

									break;
							};
						}

						break;
					}

					default :		
						throw "compression type not supported";
				}						

				break;
			}

			case 16 :
			{
				if (bih.biCompression == 3) {
					DWORD bitfields[3];

					io->read_proc(bitfields, 3 * sizeof(DWORD), 1, handle);

					dib = FreeImage_Allocate(width, height, bit_count, bitfields[0], bitfields[1], bitfields[2]);
				} else {
					dib = FreeImage_Allocate(width, height, bit_count, FI16_555_RED_MASK, FI16_555_GREEN_MASK, FI16_555_BLUE_MASK);
				}

				if (dib == NULL)
					throw "DIB allocation failed";						

				BITMAPINFOHEADER *pInfoHeader = FreeImage_GetInfoHeader(dib);
				pInfoHeader->biXPelsPerMeter = bih.biXPelsPerMeter;
				pInfoHeader->biYPelsPerMeter = bih.biYPelsPerMeter;

				if (bitmap_bits_offset > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * 3)))
					io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);

				io->read_proc(FreeImage_GetBits(dib), height * pitch, 1, handle);
#ifdef FREEIMAGE_BIGENDIAN
				for(int y = 0; y < FreeImage_GetHeight(dib); y++) {
					WORD *pixel = (WORD *)FreeImage_GetScanLine(dib, y);
					for(int x = 0; x < FreeImage_GetWidth(dib); x++) {
						SwapShort(pixel);
						pixel++;
					}
				}
#endif
				return dib;
			}

			case 24 :
			case 32 :
			{
				if( bit_count == 32 ) {
					dib = FreeImage_Allocate(width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
				} else {
					dib = FreeImage_Allocate(width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
				}

				if (dib == NULL)
					throw "DIB allocation failed";
				
				BITMAPINFOHEADER *pInfoHeader = FreeImage_GetInfoHeader(dib);
				pInfoHeader->biXPelsPerMeter = bih.biXPelsPerMeter;
				pInfoHeader->biYPelsPerMeter = bih.biYPelsPerMeter;

				// Skip over the optional palette 
				// A 24 or 32 bit DIB may contain a palette for faster color reduction

				if (bitmap_bits_offset > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * 3)))
					io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
				
				// read in the bitmap bits

				io->read_proc(FreeImage_GetBits(dib), height * pitch, 1, handle);
#ifdef FREEIMAGE_BIGENDIAN
				for(int y = 0; y < FreeImage_GetHeight(dib); y++) {
					BYTE *pixel = FreeImage_GetScanLine(dib, y);
					for(int x = 0; x < FreeImage_GetWidth(dib); x++) {
						INPLACESWAP(pixel[0], pixel[2]);
						pixel += (bit_count>>3);
					}
				}
#endif

				// check if the bitmap contains transparency, if so enable it in the header

				FreeImage_SetTransparent(dib, (FreeImage_GetColorType(dib) == FIC_RGBALPHA));

				return dib;
			}
		}
	} catch(const char *message) {
		if(dib)
			FreeImage_Unload(dib);

		FreeImage_OutputMessageProc(s_format_id, message);
	}

	return NULL;
}
コード例 #10
0
ファイル: ximatif.cpp プロジェクト: grahamboree/cppimage
	bool CxImageTIF::Decode(CxFile * hFile)
	{
		//Comment this line if you need more information on errors
		// TIFFSetErrorHandler(NULL);	//<Patrick Hoffmann>

		//Open file and fill the TIFF structure
		// m_tif = TIFFOpen(imageFileName,"rb");
		TIFF* m_tif = _TIFFOpenEx(hFile, "rb");

		uint32 height=0;
		uint32 width=0;
		uint16 bitspersample=1;
		uint16 samplesperpixel=1;
		uint32 rowsperstrip=(uint32_t)-1;
		uint16 photometric=0;
		uint16 compression=1;
		uint16 orientation=ORIENTATION_TOPLEFT; //<vho>
		uint16 res_unit; //<Trifon>
		uint32 x, y;
		float resolution, offset;
		bool isRGB;
		uint8_t *bits;		//pointer to source data
		uint8_t *bits2;	//pointer to destination data

	  cx_try
	  {
		//check if it's a tiff file
		if (!m_tif)
			cx_throw("Error encountered while opening TIFF file");

		// <Robert Abram> - 12/2002 : get NumFrames directly, instead of looping
		// info.nNumFrames=0;
		// while(TIFFSetDirectory(m_tif,(uint16)info.nNumFrames)) info.nNumFrames++;
		info.nNumFrames = TIFFNumberOfDirectories(m_tif);

		if (!TIFFSetDirectory(m_tif, (uint16)info.nFrame))
			cx_throw("Error: page not present in TIFF file");			

		//get image info
		TIFFGetField(m_tif, TIFFTAG_IMAGEWIDTH, &width);
		TIFFGetField(m_tif, TIFFTAG_IMAGELENGTH, &height);
		TIFFGetField(m_tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
		TIFFGetField(m_tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
		TIFFGetField(m_tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);   
		TIFFGetField(m_tif, TIFFTAG_PHOTOMETRIC, &photometric);
		TIFFGetField(m_tif, TIFFTAG_ORIENTATION, &orientation);

		if (info.nEscape == -1) {
			// Return output dimensions only
			head.biWidth = width;
			head.biHeight = height;
			info.dwType = CXIMAGE_FORMAT_TIF;
			cx_throw("output dimensions returned");
		}

		TIFFGetFieldDefaulted(m_tif, TIFFTAG_RESOLUTIONUNIT, &res_unit);
		if (TIFFGetField(m_tif, TIFFTAG_XRESOLUTION, &resolution))
		{
			if (res_unit == RESUNIT_CENTIMETER) resolution = (float)(resolution*2.54f + 0.5f);
			SetXDPI((int32_t)resolution);
		}
		if (TIFFGetField(m_tif, TIFFTAG_YRESOLUTION, &resolution))
		{
			if (res_unit == RESUNIT_CENTIMETER) resolution = (float)(resolution*2.54f + 0.5f);
			SetYDPI((int32_t)resolution);
		}

		if (TIFFGetField(m_tif, TIFFTAG_XPOSITION, &offset))	info.xOffset = (int32_t)offset;
		if (TIFFGetField(m_tif, TIFFTAG_YPOSITION, &offset))	info.yOffset = (int32_t)offset;

		head.biClrUsed=0;
		info.nBkgndIndex =-1;

		if (rowsperstrip>height){
			rowsperstrip=height;
			TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
		}

		isRGB = /*(bitspersample >= 8) && (VK: it is possible so for RGB to have < 8 bpp!)*/
			(photometric == PHOTOMETRIC_RGB) ||
			(photometric == PHOTOMETRIC_YCBCR) ||
			(photometric == PHOTOMETRIC_SEPARATED) ||
			(photometric == PHOTOMETRIC_LOGL) ||
			(photometric == PHOTOMETRIC_LOGLUV);

		if (isRGB){
			head.biBitCount=24;
		}else{
			if ((photometric==PHOTOMETRIC_MINISBLACK)||(photometric==PHOTOMETRIC_MINISWHITE)||(photometric==PHOTOMETRIC_PALETTE)){
				if	(bitspersample == 1){
					head.biBitCount=1;		//B&W image
					head.biClrUsed =2;
				} else if (bitspersample == 4) {
					head.biBitCount=4;		//16 colors gray scale
					head.biClrUsed =16;
				} else {
					head.biBitCount=8;		//gray scale
					head.biClrUsed =256;
				}
			} else if (bitspersample == 4) {
				head.biBitCount=4;			// 16 colors
				head.biClrUsed=16;
			} else {
				head.biBitCount=8;			//256 colors
				head.biClrUsed=256;
			}

			if ((bitspersample > 8) && (photometric==PHOTOMETRIC_PALETTE))	// + VK + (BIG palette! => convert to RGB)
			{	head.biBitCount=24;
				head.biClrUsed =0;
			}
		}

		if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding

		Create(width,height,head.biBitCount,CXIMAGE_FORMAT_TIF);	//image creation
		if (!pDib) cx_throw("CxImageTIF can't create image");

	#if CXIMAGE_SUPPORT_ALPHA
		if (samplesperpixel==4) AlphaCreate();	//add alpha support for 32bpp tiffs
		if (samplesperpixel==2 && bitspersample==8) AlphaCreate();	//add alpha support for 8bpp + alpha
	#endif //CXIMAGE_SUPPORT_ALPHA

		TIFFGetField(m_tif, TIFFTAG_COMPRESSION, &compression);
		SetCodecOption(compression); // <DPR> save original compression type

		if (isRGB) {
			// 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) cx_throw("No space for raster buffer");
				
			// Read the image in one chunk into an RGBA array
			if(!TIFFReadRGBAImage(m_tif, width, height, raster, 1)) {
					_TIFFfree(raster);
					cx_throw("Corrupted TIFF file!");
			}

			// 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 = info.pImage;
			for (y = 0; y < height; y++) {

				if (info.nEscape){ // <vho> - cancel decoding
					_TIFFfree(raster);
					cx_throw("Cancelled");
				}

				bits = bits2;
				for (x = 0; x < width; x++) {
					*bits++ = (uint8_t)TIFFGetB(row[x]);
					*bits++ = (uint8_t)TIFFGetG(row[x]);
					*bits++ = (uint8_t)TIFFGetR(row[x]);
	#if CXIMAGE_SUPPORT_ALPHA
					if (samplesperpixel==4) AlphaSet(x,y,(uint8_t)TIFFGetA(row[x]));
	#endif //CXIMAGE_SUPPORT_ALPHA
				}
				row += width;
				bits2 += info.dwEffWidth;
			}
			_TIFFfree(raster);
		} else {
			int32_t BIG_palette = (bitspersample > 8) &&	// + VK
							  (photometric==PHOTOMETRIC_PALETTE);		
			if (BIG_palette && (bitspersample > 24))	// + VK
				cx_throw("Too big palette to handle");		// + VK

			RGBQuad *pal;
			pal=(RGBQuad*)calloc(BIG_palette ? 1<<bitspersample : 256,sizeof(RGBQuad)); 
				// ! VK: it coasts nothing but more correct to use 256 as temp palette storage
				// ! VK: but for case of BIG palette it just copied
			if (pal==NULL) cx_throw("Unable to allocate TIFF palette");

			int32_t bpp = bitspersample <= 8 ? bitspersample : 8; // + VK (to use instead of bitspersample for case of > 8)

			// set up the colormap based on photometric	
			switch(photometric) {
				case PHOTOMETRIC_MINISBLACK:	// bitmap and greyscale image types
				case PHOTOMETRIC_MINISWHITE:
					if (bitspersample == 1) {	// Monochrome image
						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 (int32_t i=0; i<(1<<bpp); i++){
								pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = (uint8_t)(i*(255/((1<<bpp)-1)));
							}
						} else {
							for (int32_t i=0; i<(1<<bpp); i++){
								pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = (uint8_t)(255-i*(255/((1<<bpp)-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*/ BIG_palette;
					if (!BIG_palette) {
						int32_t n= 1<<bpp;
						while (n-- > 0) {
							if (red[n] >= 256 || green[n] >= 256 || blue[n] >= 256) {
								Palette16Bits=true;
								break;
							}
						}
					}

					// load the palette in the DIB
					for (int32_t i = (1 << ( BIG_palette ? bitspersample : bpp )) - 1; i >= 0; i--) {
						if (Palette16Bits) {
							pal[i].rgbRed =(uint8_t) CVT(red[i]);
							pal[i].rgbGreen = (uint8_t) CVT(green[i]);
							pal[i].rgbBlue = (uint8_t) CVT(blue[i]);           
						} else {
							pal[i].rgbRed = (uint8_t) red[i];
							pal[i].rgbGreen = (uint8_t) green[i];
							pal[i].rgbBlue = (uint8_t) blue[i];        
						}
					}
					break;
			}
			if (!BIG_palette) { // + VK (BIG palette is stored until image is ready)
				SetPalette(pal,/*head.biClrUsed*/ 1<<bpp);	//palette assign // * VK
				free(pal); 
				pal = NULL; 
			}

			// read the tiff lines and save them in the DIB
			uint32 nrow;
			uint32 ys;
			int32_t line = CalculateLine(width, bitspersample * samplesperpixel);
			
			int32_t bitsize = TIFFStripSize(m_tif);
			//verify bitsize: could be wrong if StripByteCounts is missing.
			if (bitsize>(int32_t)(head.biSizeImage*samplesperpixel))
				bitsize = head.biSizeImage*samplesperpixel;
			if (bitsize<(int32_t)(info.dwEffWidth*rowsperstrip))
				bitsize = info.dwEffWidth*rowsperstrip;

			if ((bitspersample > 8) && (bitspersample != 16))	// + VK (for bitspersample == 9..15,17..32..64
				bitsize *= (bitspersample + 7)/8; 

			int32_t tiled_image = TIFFIsTiled(m_tif);
			uint32 tw=0, tl=0;
			uint8_t* tilebuf=NULL;
			if (tiled_image){
				TIFFGetField(m_tif, TIFFTAG_TILEWIDTH, &tw);
				TIFFGetField(m_tif, TIFFTAG_TILELENGTH, &tl);
				rowsperstrip = tl;
				bitsize = TIFFTileSize(m_tif) * (int32_t)(1+width/tw);
				tilebuf = (uint8_t*)malloc(TIFFTileSize(m_tif));
			}
			
			bits = (uint8_t*)malloc(bitspersample==16? bitsize*2 : bitsize); // * VK
			uint8_t * bits16 = NULL;										  // + VK
			int32_t line16    = 0;											  // + VK

			if (!tiled_image && bitspersample==16) {					  // + VK +
				line16 = line;
				line   = CalculateLine(width, 8 * samplesperpixel);
				bits16 = bits;
				bits   = (uint8_t*)malloc(bitsize);
			}

			if (bits==NULL){
				if (bits16) free(bits16);								  // + VK
				if (pal)	free(pal);									  // + VK
				if (tilebuf)free(tilebuf);								  // + VK	
				cx_throw("CxImageTIF can't allocate memory");
			}

	#ifdef FIX_16BPP_DARKIMG // + VK: for each line, store shift count bits used to fix it
			uint8_t* row_shifts = NULL;
			if (bits16) row_shifts = (uint8_t*)malloc(height); 
	#endif

			for (ys = 0; ys < height; ys += rowsperstrip) {

				if (info.nEscape){ // <vho> - cancel decoding
					free(bits);
					cx_throw("Cancelled");
				}

				nrow = (ys + rowsperstrip > height ? height - ys : rowsperstrip);

				if (tiled_image){
					uint32 imagew = TIFFScanlineSize(m_tif);
					uint32 tilew  = TIFFTileRowSize(m_tif);
					int32_t iskew = imagew - tilew;
					uint8* bufp = (uint8*) bits;

					uint32 colb = 0;
					for (uint32 col = 0; col < width; col += tw) {
						if (TIFFReadTile(m_tif, tilebuf, col, ys, 0, 0) < 0){
							free(tilebuf);
							free(bits);
							cx_throw("Corrupted tiled TIFF file!");
						}

						if (colb + tw > imagew) {
							uint32 owidth = imagew - colb;
							uint32 oskew = tilew - owidth;
							TileToStrip(bufp + colb, tilebuf, nrow, owidth, oskew + iskew, oskew );
						} else {
							TileToStrip(bufp + colb, tilebuf, nrow, tilew, iskew, 0);
						}
						colb += tilew;
					}

				} else {
					if (TIFFReadEncodedStrip(m_tif, TIFFComputeStrip(m_tif, ys, 0), 
						(bits16? bits16 : bits), nrow * (bits16 ? line16 : line)) == -1) { // * VK

	#ifdef NOT_IGNORE_CORRUPTED
						free(bits);
						if (bits16) free(bits16);  // + VK
						cx_throw("Corrupted TIFF file!");
	#else
						break;
	#endif
					}
				}

				for (y = 0; y < nrow; y++) {
					int32_t offset=(nrow-y-1)*line;
					if ((bitspersample==16) && !BIG_palette) {	// * VK
						int32_t offset16 = (nrow-y-1)*line16;		// + VK
						if (bits16)	{							// + VK +
	#ifdef FIX_16BPP_DARKIMG
							int32_t the_shift;
							uint8_t hi_byte, hi_max=0;
							uint32_t xi;
							for (xi=0;xi<(uint32)line;xi++) {
								hi_byte = bits16[xi*2+offset16+1];
								if(hi_byte>hi_max)
									hi_max = hi_byte;
							}
							the_shift = (hi_max == 0) ? 8 : 0;
							if (!the_shift)
								while( ! (hi_max & 0x80) ) {
									the_shift++;
									hi_max <<= 1;
								}
							row_shifts[height-ys-nrow+y] = the_shift;
							the_shift = 8 - the_shift;
							for (xi=0;xi<(uint32)line;xi++) 
								bits[xi+offset]= ((bits16[xi*2+offset16+1]<<8) | bits16[xi*2+offset16]) >> the_shift;
	#else
							for (uint32_t xi=0;xi<(uint32)line;xi++) 
								bits[xi+offset]=bits16[xi*2+offset16+1];
	#endif
						} else {
							for (uint32_t xi=0;xi<width;xi++)
								bits[xi+offset]=bits[xi*2+offset+1];
								}
					}
					if (samplesperpixel==1) { 
						if (BIG_palette)
							if (bits16) {
								int32_t offset16 = (nrow-y-1)*line16;		// + VK
								MoveBitsPal( info.pImage + info.dwEffWidth * (height-ys-nrow+y),
										 bits16 + offset16, width, bitspersample, pal );
							} else
								MoveBitsPal( info.pImage + info.dwEffWidth * (height-ys-nrow+y),
										 bits + offset, width, bitspersample, pal );
						else if ((bitspersample == head.biBitCount) || 
							(bitspersample == 16))	//simple 8bpp, 4bpp image or 16bpp
							memcpy(info.pImage+info.dwEffWidth*(height-ys-nrow+y),bits+offset,min((unsigned)line, info.dwEffWidth));
						else
							MoveBits( info.pImage + info.dwEffWidth * (height-ys-nrow+y),
									  bits + offset, width, bitspersample );
					} else if (samplesperpixel==2) { //8bpp image with alpha layer
						int32_t xi=0;
						int32_t ii=0;
						int32_t yi=height-ys-nrow+y;
	#if CXIMAGE_SUPPORT_ALPHA
						if (!pAlpha) AlphaCreate();			// + VK
	#endif //CXIMAGE_SUPPORT_ALPHA
						while (ii<line){
							SetPixelIndex(xi,yi,bits[ii+offset]);
	#if CXIMAGE_SUPPORT_ALPHA
							AlphaSet(xi,yi,bits[ii+offset+1]);
	#endif //CXIMAGE_SUPPORT_ALPHA
							ii+=2;
							xi++;
							if (xi>=(int32_t)width){
								yi--;
								xi=0;
							}
						}
					} else { //photometric==PHOTOMETRIC_CIELAB
						if (head.biBitCount!=24){ //fix image
							Create(width,height,24,CXIMAGE_FORMAT_TIF);
	#if CXIMAGE_SUPPORT_ALPHA
							if (samplesperpixel==4) AlphaCreate();
	#endif //CXIMAGE_SUPPORT_ALPHA
						}

						int32_t xi=0;
						uint32 ii=0;
						int32_t yi=height-ys-nrow+y;
						RGBQuad c;
						int32_t l,a,b,bitsoffset;
						double p,cx,cy,cz,cr,cg,cb;
						while (ii</*line*/width){		// * VK
							bitsoffset = ii*samplesperpixel+offset;
							l=bits[bitsoffset];
							a=bits[bitsoffset+1];
							b=bits[bitsoffset+2];
							if (a>127) a-=256;
							if (b>127) b-=256;
							// lab to xyz
							p = (l/2.55 + 16) / 116.0;
							cx = pow( p + a * 0.002, 3);
							cy = pow( p, 3);
							cz = pow( p - b * 0.005, 3);
							// white point
							cx*=0.95047;
							//cy*=1.000;
							cz*=1.0883;
							// xyz to rgb
							cr =  3.240479 * cx - 1.537150 * cy - 0.498535 * cz;
							cg = -0.969256 * cx + 1.875992 * cy + 0.041556 * cz;
							cb =  0.055648 * cx - 0.204043 * cy + 1.057311 * cz;

							if ( cr > 0.00304 ) cr = 1.055 * pow(cr,0.41667) - 0.055;
								else            cr = 12.92 * cr;
							if ( cg > 0.00304 ) cg = 1.055 * pow(cg,0.41667) - 0.055;
								else            cg = 12.92 * cg;
							if ( cb > 0.00304 ) cb = 1.055 * pow(cb,0.41667) - 0.055;
								else            cb = 12.92 * cb;

							c.rgbRed  =(uint8_t)max(0,min(255,(int32_t)(cr*255)));
							c.rgbGreen=(uint8_t)max(0,min(255,(int32_t)(cg*255)));
							c.rgbBlue =(uint8_t)max(0,min(255,(int32_t)(cb*255)));

							SetPixelColor(xi,yi,c);
	#if CXIMAGE_SUPPORT_ALPHA
							if (samplesperpixel==4) AlphaSet(xi,yi,bits[bitsoffset+3]);
	#endif //CXIMAGE_SUPPORT_ALPHA
							ii++;
							xi++;
							if (xi>=(int32_t)width){
								yi--;
								xi=0;
							}
						}
					}
				}
			}
			free(bits);
			if (bits16) free(bits16);

	#ifdef FIX_16BPP_DARKIMG
			if (row_shifts && (samplesperpixel == 1) && (bitspersample==16) && !BIG_palette) {
				// 1. calculate maximum necessary shift
				int32_t min_row_shift = 8;
				for( y=0; y<height; y++ ) {
					if (min_row_shift > row_shifts[y]) min_row_shift = row_shifts[y];
				}
				// 2. for rows having less shift value, correct such rows:
				for( y=0; y<height; y++ ) {
					if (min_row_shift < row_shifts[y]) {
						int32_t need_shift = row_shifts[y] - min_row_shift;
						uint8_t* data = info.pImage + info.dwEffWidth * y;
						for( x=0; x<width; x++, data++ )
							*data >>= need_shift;
					}
				}
コード例 #11
0
ファイル: PluginPCD.cpp プロジェクト: Ayane/BLPConverter
static FIBITMAP * DLL_CALLCONV
Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
	int width;
	int height;
	int line;
	int pitch;
	int bpp = 24;
	int scan_line_add   = 1;
	int start_scan_line = 0;

	// to make absolute seeks possible we store the current position in the file
	
	long offset_in_file = io->tell_proc(handle);
	long seek = 0;

	// decide which bitmap in the cabinet to load

	switch (flags) {
		case PCD_BASEDIV4 :
			seek = 0x2000;
			width = 192;
			height = 128;
			break;

		case PCD_BASEDIV16 :
			seek = 0xB800;
			width = 384;
			height = 256;
			break;

		default :
			seek = 0x30000;
			width = 768;
			height = 512;
			break;
	}

	// calculate line and pitch based on the selected bitmap size

	line = CalculateLine(width, bpp);
	pitch = CalculatePitch(line);

	// allocate the dib and write out the header

	FIBITMAP *dib = FreeImage_Allocate(width, height, bpp, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
	
	// check if the PCD is bottom-up

	if (VerticalOrientation(io, handle)) {
		scan_line_add = -1;
		start_scan_line = height - 1;		
	}

	// temporary stuff to load PCD

	BYTE *y1   = new BYTE[width];
	BYTE *y2   = new BYTE[width];
	BYTE *cbcr = new BYTE[width];
	BYTE *yl[] = { y1, y2 };

	// seek to the part where the bitmap data begins

	io->seek_proc(handle, offset_in_file, SEEK_SET);
	io->seek_proc(handle, seek, SEEK_CUR);

	// read the data

	for (int y = 0; y < height / 2; ++y) {
		io->read_proc(y1, width, 1, handle);
		io->read_proc(y2, width, 1, handle);
		io->read_proc(cbcr, width, 1, handle);

		for (int i = 0; i < 2; ++i) {
			BYTE *img = FreeImage_GetScanLine(dib, start_scan_line);
			for (int x = 0; x < width; ++x) {
				int r, g, b;

				YUV2RGB(yl[i][x], cbcr[x / 2], cbcr[(width / 2) + (x / 2)], r, g, b);

				img[FI_RGBA_BLUE]  = (BYTE)b;
				img[FI_RGBA_GREEN] = (BYTE)g;
				img[FI_RGBA_RED]   = (BYTE)r;
				img += 3;
			}

			start_scan_line += scan_line_add;
		}
	}

	delete [] cbcr;
	delete [] y2;
	delete [] y1;

	return dib;
}
コード例 #12
0
bool COverlaySurfaceCache::CopyToSharedMemory(IDirectDraw7*pDDraw,const OVERLAY_ITEM& item)
{
	CAutoLockEx<CMutexLock> lock(g_mLock);
	
	if( !item.pOverlay ) return false;

	DumpSurface(item.pOverlay,_T("DumpSurface1.temp"));
	CComPtr<IDirectDrawSurface7> pTemp = CopyToOffscreenSurface(pDDraw,item);
	DumpSurface(pTemp,_T("DumpSurface2.temp"));
	if(!pTemp) 
	{
		OutputDebugStringA("CopyToOffscreenSurface failed");
		return false;
	}

	HRESULT hr=S_OK;
	DDSURFACEDESC2 ddsd_dest = {0};
	ddsd_dest.dwSize = sizeof(DDSURFACEDESC2);

	hr = pTemp->Lock(0,&ddsd_dest,DDLOCK_READONLY|DDLOCK_DONOTWAIT,0);
	if (FAILED(hr))
	{
		OutputDebugStringA("IDirectDrawSurface7::Lock failed");
		pTemp->Unlock(0);
		return false;
	}
	try
	{
		DWORD rgnsize = 0;
// 		CComPtr<IDirectDrawClipper> pClipper;
// 		if(SUCCEEDED(item.pOverlay->GetClipper(&pClipper)))
// 		{
// 			pClipper->GetClipList(0,0,&rgnsize);
// 		}

		DWORD size;
		DWORD imagesize ;


		imagesize = CalculatePitch(CalculateLine(ddsd_dest.dwWidth,ddsd_dest.ddpfPixelFormat.dwRGBBitCount)) * ddsd_dest.dwHeight;
		size = FIELD_OFFSET(SURFACE_DATA,data) + (rgnsize?rgnsize-sizeof(RGNDATAHEADER):0) + imagesize;


		CFileMapping mem;
		if(!mem.Open(kChaptureOverlayShareMemory,size,false))
		{
			// open failed ,maybe size is too small
			if(mem.Open(kChaptureOverlayShareMemory,sizeof(SURFACE_DATA),false))
			{
				SURFACE_DATA*pData = (SURFACE_DATA*)mem.GetPointer();
				pData->size = size;
				pData->desc = ddsd_dest;
				pData->modified = TRUE;
			}
			OutputDebugStringA("CFileMappingBitmap::Open failed");
			throw E_FAIL;
		}
		SURFACE_DATA*pData = (SURFACE_DATA*)mem.GetPointer();
		pData->size = size;
		pData->desc = ddsd_dest;
		pData->modified = TRUE;
// 		if(pClipper && rgnsize)
// 		{
// 			if(FAILED(pClipper->GetClipList(0,(LPRGNDATA)&pData->rdh,&rgnsize)))
// 			{
// 				OutputDebugStringA("IDirectDrawSurface7::GetClipList failed");
// 				throw E_FAIL;
// 			}
// 		}

// 		if(item.bEntireDest)
// 		{
// 			DDSURFACEDESC2 des = {0};
// 			des.dwSize = sizeof(DDSURFACEDESC2);
// 			if(FAILED(pPrimary->GetSurfaceDesc(&des)))
// 			{
// 				OutputDebugStringA("IDirectDrawSurface7::GetSurfaceDesc failed");
// 				throw E_FAIL;
// 			}
// 			pData->rcDst.left = pData->rcDst.top = 0;
// 			pData->rcDst.right = des.dwWidth;
// 			pData->rcDst.bottom = des.dwHeight;
// 		}
// 		else
			pData->rcDst = item.rcDst;

		pData->flags= item.flags; 
		pData->fx = item.fx;

		BYTE *pBegin = pData->data + (rgnsize?rgnsize-sizeof(RGNDATAHEADER):0);
		pData->desc.lPitch = CalculatePitch(CalculateLine(ddsd_dest.dwWidth,ddsd_dest.ddpfPixelFormat.dwRGBBitCount));
		//int left ;
		//left = CalculatePitch(CalculateLine(item.rcDst.left,ddsd_dest.ddpfPixelFormat.dwRGBBitCount));

		for (int i= 0;i != ddsd_dest.dwHeight;i++)
		{
			memcpy( pBegin + i *  pData->desc.lPitch ,
				(BYTE*)ddsd_dest.lpSurface + i*ddsd_dest.lPitch ,
				pData->desc.lPitch);
		}

// 		DebugOutF(filelog::log_info,"CopyToSharedMemory (%d,%d,%d,%d) -> (%d,%d,%d,%d) ok",
// 			item.rcSrc.left,
// 			item.rcSrc.top,
// 			item.rcSrc.right,
// 			item.rcSrc.bottom,
// 			item.rcDst.left,
// 			item.rcDst.top,
// 			item.rcDst.right,
// 			item.rcDst.bottom);
	}
	catch(HRESULT hr1)
	{
		hr = hr1;
	}
	pTemp->Unlock(0);
	return SUCCEEDED(hr);
}
コード例 #13
0
ファイル: ximatif.cpp プロジェクト: dehilsterlexis/eclide-1
bool CxImageTIF::Decode(CxFile * hFile)
{
    //Comment this line if you need more information on errors
    // TIFFSetErrorHandler(NULL);	//<Patrick Hoffmann>

    //Open file and fill the TIFF structure
    // m_tif = TIFFOpen(imageFileName,"rb");
    TIFF* m_tif = _TIFFOpenEx(hFile, "rb");

    uint32 height=0;
    uint32 width=0;
    uint16 bitspersample=1;
    uint16 samplesperpixel=1;
    uint32 rowsperstrip=(DWORD)-1;
    uint16 photometric=0;
    uint16 compression=1;
    uint16 orientation=ORIENTATION_TOPLEFT; //<vho>
    uint16 res_unit; //<Trifon>
    uint32 x, y;
    float resolution, offset;
    BOOL isRGB;
    BYTE *bits;		//pointer to source data
    BYTE *bits2;	//pointer to destination data

  try{
    //check if it's a tiff file
    if (!m_tif)
        throw "Error encountered while opening TIFF file";

    // <Robert Abram> - 12/2002 : get NumFrames directly, instead of looping
    // info.nNumFrames=0;
    // while(TIFFSetDirectory(m_tif,(uint16)info.nNumFrames)) info.nNumFrames++;
    info.nNumFrames = TIFFNumberOfDirectories(m_tif);

    if (!TIFFSetDirectory(m_tif, (uint16)info.nFrame))
        throw "Error: page not present in TIFF file";			

    //get image info
    TIFFGetField(m_tif, TIFFTAG_IMAGEWIDTH, &width);
    TIFFGetField(m_tif, TIFFTAG_IMAGELENGTH, &height);
    TIFFGetField(m_tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
    TIFFGetField(m_tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
    TIFFGetField(m_tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);   
    TIFFGetField(m_tif, TIFFTAG_PHOTOMETRIC, &photometric);
    TIFFGetField(m_tif, TIFFTAG_ORIENTATION, &orientation);

    if (info.nEscape == -1) {
        // Return output dimensions only
        head.biWidth = width;
        head.biHeight = height;
        throw "output dimensions returned";
    }

    TIFFGetFieldDefaulted(m_tif, TIFFTAG_RESOLUTIONUNIT, &res_unit);
    if (TIFFGetField(m_tif, TIFFTAG_XRESOLUTION, &resolution))
    {
        if (res_unit == RESUNIT_CENTIMETER) resolution = (float)(resolution*2.54f + 0.5f);
        SetXDPI((long)resolution);
    }
    if (TIFFGetField(m_tif, TIFFTAG_YRESOLUTION, &resolution))
    {
        if (res_unit == RESUNIT_CENTIMETER) resolution = (float)(resolution*2.54f + 0.5f);
        SetYDPI((long)resolution);
    }

    if (TIFFGetField(m_tif, TIFFTAG_XPOSITION, &offset))	info.xOffset = (long)offset;
    if (TIFFGetField(m_tif, TIFFTAG_YPOSITION, &offset))	info.yOffset = (long)offset;

    head.biClrUsed=0;
    info.nBkgndIndex =-1;

    if (rowsperstrip>height){
        rowsperstrip=height;
        TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
    }

    isRGB = (bitspersample >= 8) &&
        (photometric == PHOTOMETRIC_RGB) ||
        (photometric == PHOTOMETRIC_YCBCR) ||
        (photometric == PHOTOMETRIC_SEPARATED) ||
        (photometric == PHOTOMETRIC_LOGL) ||
        (photometric == PHOTOMETRIC_LOGLUV);

    if (isRGB){
        head.biBitCount=24;
    }else{
        if ((photometric==PHOTOMETRIC_MINISBLACK)||(photometric==PHOTOMETRIC_MINISWHITE)){
            if	(bitspersample == 1){
                head.biBitCount=1;		//B&W image
                head.biClrUsed =2;
            } else if (bitspersample == 4) {
                head.biBitCount=4;		//16 colors gray scale
                head.biClrUsed =16;
            } else {
                head.biBitCount=8;		//gray scale
                head.biClrUsed =256;
            }
        } else if (bitspersample == 4) {
            head.biBitCount=4;			// 16 colors
            head.biClrUsed=16;
        } else {
            head.biBitCount=8;			//256 colors
            head.biClrUsed=256;
        }
    }

    if (info.nEscape) throw "Cancelled"; // <vho> - cancel decoding

    Create(width,height,head.biBitCount,CXIMAGE_FORMAT_TIF);	//image creation
    if (!pDib) throw "CxImageTIF can't create image";

#if CXIMAGE_SUPPORT_ALPHA
    if (samplesperpixel==4) AlphaCreate();	//add alpha support for 32bpp tiffs
    if (samplesperpixel==2 && bitspersample==8) AlphaCreate();	//add alpha support for 8bpp + alpha
#endif //CXIMAGE_SUPPORT_ALPHA

    TIFFGetField(m_tif, TIFFTAG_COMPRESSION, &compression);
    SetCodecOption(compression); // <DPR> save original compression type

    if (isRGB) {
        // 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) throw "No space for raster buffer";
            
        // Read the image in one chunk into an RGBA array
        if(!TIFFReadRGBAImage(m_tif, width, height, raster, 1)) {
                _TIFFfree(raster);
                throw "Corrupted TIFF file!";
        }

        // 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 = info.pImage;
        for (y = 0; y < height; y++) {

            if (info.nEscape){ // <vho> - cancel decoding
                _TIFFfree(raster);
                throw "Cancelled";
            }

            bits = bits2;
            for (x = 0; x < width; x++) {
                *bits++ = (BYTE)TIFFGetB(row[x]);
                *bits++ = (BYTE)TIFFGetG(row[x]);
                *bits++ = (BYTE)TIFFGetR(row[x]);
#if CXIMAGE_SUPPORT_ALPHA
                if (samplesperpixel==4) AlphaSet(x,y,(BYTE)TIFFGetA(row[x]));
#endif //CXIMAGE_SUPPORT_ALPHA
            }
            row += width;
            bits2 += info.dwEffWidth;
        }
        _TIFFfree(raster);
    } else {
        RGBQUAD *pal;
        pal=(RGBQUAD*)calloc(256,sizeof(RGBQUAD));
        if (pal==NULL) throw "Unable to allocate TIFF palette";

        // set up the colormap based on photometric	
        switch(photometric) {
            case PHOTOMETRIC_MINISBLACK:	// bitmap and greyscale image types
            case PHOTOMETRIC_MINISWHITE:
                if (bitspersample == 1) {	// Monochrome image
                    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 (DWORD i=0; i<head.biClrUsed; i++){
                            pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = (BYTE)(i*(255/(head.biClrUsed-1)));
                        }
                    } else {
                        for (DWORD i=0; i<head.biClrUsed; i++){
                            pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = (BYTE)(255-i*(255/(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;
        }
        SetPalette(pal,head.biClrUsed);	//palette assign
        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)(head.biSizeImage*samplesperpixel)) bitsize=head.biSizeImage*samplesperpixel;

        int tiled_image = TIFFIsTiled(m_tif);
        uint32 tw, tl;
        BYTE* tilebuf;
        if (tiled_image){
            TIFFGetField(m_tif, TIFFTAG_TILEWIDTH, &tw);
            TIFFGetField(m_tif, TIFFTAG_TILELENGTH, &tl);
            rowsperstrip = tl;
            bitsize = TIFFTileSize(m_tif) * (int)(1+width/tw);
            tilebuf = (BYTE*)malloc(TIFFTileSize(m_tif));
        }
        
        bits = (BYTE*)malloc(bitsize);
        if (bits==NULL){
            throw "CxImageTIF can't allocate memory";
        }

        for (ys = 0; ys < height; ys += rowsperstrip) {

            if (info.nEscape){ // <vho> - cancel decoding
                free(bits);
                throw "Cancelled";
            }

            nrow = (ys + rowsperstrip > height ? height - ys : rowsperstrip);

            if (tiled_image){
                uint32 imagew = TIFFScanlineSize(m_tif);
                uint32 tilew  = TIFFTileRowSize(m_tif);
                int iskew = imagew - tilew;
                uint8* bufp = (uint8*) bits;

                uint32 colb = 0;
                for (uint32 col = 0; col < width; col += tw) {
                    if (TIFFReadTile(m_tif, tilebuf, col, ys, 0, 0) < 0){
                        free(tilebuf);
                        free(bits);
                        throw "Corrupted tiled TIFF file!";
                    }

                    if (colb + tw > imagew) {
                        uint32 owidth = imagew - colb;
                        uint32 oskew = tilew - owidth;
                        TileToStrip(bufp + colb, tilebuf, nrow, owidth, oskew + iskew, oskew );
                    } else {
                        TileToStrip(bufp + colb, tilebuf, nrow, tilew, iskew, 0);
                    }
                    colb += tilew;
                }

            } else {
                if (TIFFReadEncodedStrip(m_tif, TIFFComputeStrip(m_tif, ys, 0), bits, nrow * line) == -1) {
                    free(bits);
                    throw "Corrupted TIFF file!";
                }
            }

            for (y = 0; y < nrow; y++) {
                long offset=(nrow-y-1)*line;
                if (bitspersample==16) for (DWORD xi=0;xi<width;xi++) bits[xi+offset]=bits[xi*2+offset+1];
                if (samplesperpixel==1) { //simple 8bpp image
                    memcpy(info.pImage+info.dwEffWidth*(height-ys-nrow+y),bits+offset,info.dwEffWidth);
                } else if (samplesperpixel==2) { //8bpp image with alpha layer
                    int xi=0;
                    int ii=0;
                    int yi=height-ys-nrow+y;
                    while (ii<line){
                        SetPixelIndex(xi,yi,bits[ii+offset]);
#if CXIMAGE_SUPPORT_ALPHA
                        AlphaSet(xi,yi,bits[ii+offset+1]);
#endif //CXIMAGE_SUPPORT_ALPHA
                        ii+=2;
                        xi++;
                        if (xi>=(int)width){
                            yi--;
                            xi=0;
                        }
                    }
                } else { //photometric==PHOTOMETRIC_CIELAB
                    if (head.biBitCount!=24){ //fix image
                        Create(width,height,24,CXIMAGE_FORMAT_TIF);
#if CXIMAGE_SUPPORT_ALPHA
                        if (samplesperpixel==4) AlphaCreate();
#endif //CXIMAGE_SUPPORT_ALPHA
                    }

                    int xi=0;
                    int ii=0;
                    int yi=height-ys-nrow+y;
                    RGBQUAD c;
                    int l,a,b,bitsoffset;
                    double p,cx,cy,cz,cr,cg,cb;
                    while (ii<line){
                        bitsoffset = ii*samplesperpixel+offset;
                        l=bits[bitsoffset];
                        a=bits[bitsoffset+1];
                        b=bits[bitsoffset+2];
                        if (a>127) a-=256;
                        if (b>127) b-=256;
                        // lab to xyz
                        p = (l/2.55 + 16) / 116.0;
                        cx = pow( p + a * 0.002, 3);
                        cy = pow( p, 3);
                        cz = pow( p - b * 0.005, 3);
                        // white point
                        cx*=0.95047;
                        //cy*=1.000;
                        cz*=1.0883;
                        // xyz to rgb
                        cr =  3.240479 * cx - 1.537150 * cy - 0.498535 * cz;
                        cg = -0.969256 * cx + 1.875992 * cy + 0.041556 * cz;
                        cb =  0.055648 * cx - 0.204043 * cy + 1.057311 * cz;

                        if ( cr > 0.00304 ) cr = 1.055 * pow(cr,0.41667) - 0.055;
                            else            cr = 12.92 * cr;
                        if ( cg > 0.00304 ) cg = 1.055 * pow(cg,0.41667) - 0.055;
                            else            cg = 12.92 * cg;
                        if ( cb > 0.00304 ) cb = 1.055 * pow(cb,0.41667) - 0.055;
                            else            cb = 12.92 * cb;

                        c.rgbRed  =(BYTE)max(0,min(255,(int)(cr*255)));
                        c.rgbGreen=(BYTE)max(0,min(255,(int)(cg*255)));
                        c.rgbBlue =(BYTE)max(0,min(255,(int)(cb*255)));

                        SetPixelColor(xi,yi,c);
#if CXIMAGE_SUPPORT_ALPHA
                        if (samplesperpixel==4) AlphaSet(xi,yi,bits[bitsoffset+3]);
#endif //CXIMAGE_SUPPORT_ALPHA
                        ii++;
                        xi++;
                        if (xi>=(int)width){
                            yi--;
                            xi=0;
                        }
                    }
                }
            }
        }
        free(bits);
        if (tiled_image) free(tilebuf);

        switch(orientation){
        case ORIENTATION_TOPRIGHT: /* row 0 top, col 0 rhs */
            Mirror();
            break;
        case ORIENTATION_BOTRIGHT: /* row 0 bottom, col 0 rhs */
            Flip();
            Mirror();
            break;
        case ORIENTATION_BOTLEFT: /* row 0 bottom, col 0 lhs */
            Flip();
            break;
        case ORIENTATION_LEFTTOP: /* row 0 lhs, col 0 top */
            RotateRight();
            Mirror();
            break;
        case ORIENTATION_RIGHTTOP: /* row 0 rhs, col 0 top */
            RotateLeft();
            break;
        case ORIENTATION_RIGHTBOT: /* row 0 rhs, col 0 bottom */
            RotateLeft();
            Mirror();
            break;
        case ORIENTATION_LEFTBOT: /* row 0 lhs, col 0 bottom */
            RotateRight();
            break;
        }

    }
  } catch (char *message) {
      strncpy(info.szLastError,message,255);
      if (m_tif) TIFFClose(m_tif);
      if (info.nEscape==-1) return true;
      return false;
  }
    TIFFClose(m_tif);
    return true;
}