Beispiel #1
0
CVertMeshViewer::CVertMeshViewer(UVertMesh* Mesh, CApplication* Window)
:	CMeshViewer(Mesh, Window)
,	AnimIndex(-1)
{
	CVertMeshInstance *VertInst = new CVertMeshInstance();
	VertInst->SetMesh(Mesh);
	Inst = VertInst;

	CVertMeshInstance *MeshInst = static_cast<CVertMeshInstance*>(Inst);
	// compute model center by Z-axis (vertical)
	CVec3 offset;
	const FBox &B = Mesh->BoundingBox;
#if 1
	VectorAdd(CVT(B.Min), CVT(B.Max), offset);
	offset.Scale(0.5f);
	MeshInst->BaseTransformScaled.TransformPointSlow(offset, offset);
#else
	// scale/translate origin
	float z = (B.Max.Z + B.Min.Z) / 2;
	z = (z - Mesh->MeshOrigin.Z) * Mesh->MeshScale.Z;	//!! bad formula
	offset.Set(0, 0, z);
#endif
	offset[2] += Mesh->BoundingSphere.R / 20;			// offset a bit up
	// offset view
	SetViewOffset(offset);
	// automatically scale view distance depending on model size
	float Radius = Mesh->BoundingSphere.R;
	if (Radius < 10) Radius = 10;
	SetDistScale(Mesh->MeshScale.X * Radius / 150);
}
Beispiel #2
0
// function is similar to part of CSkelMeshInstance::SetMesh()
static void BuildSkeleton(TArray<CCoords> &Coords, const TArray<RJoint> &Bones, const TArray<AnalogTrack> &Anim)
{
	guard(BuildSkeleton);

	int numBones = Anim.Num();
	Coords.Empty(numBones);
	Coords.AddZeroed(numBones);

	for (int i = 0; i < numBones; i++)
	{
		const AnalogTrack &A = Anim[i];
		const RJoint &B = Bones[i];
		CCoords &BC = Coords[i];
		// compute reference bone coords
		CVec3 BP;
		CQuat BO;
		// get default pose
		BP = CVT(A.KeyPos[0]);
		BO = CVT(A.KeyQuat[0]);
		if (!i) BO.Conjugate();

		BC.origin = BP;
		BO.ToAxis(BC.axis);
		// move bone position to global coordinate space
		if (i)	// do not rotate root bone
		{
			assert(B.parent >= 0);
			Coords[B.parent].UnTransformCoords(BC, BC);
		}
	}

	unguard;
}
// helper for gradHist, quantize O and M into O0, O1 and M0, M1 (uses sse)
void gradQuantize( float *O, float *M, int *O0, int *O1, float *M0, float *M1,
  int nOrients, int nb, int n, float norm )
{
  // assumes all *OUTPUT* matrices are 4-byte aligned
  int i, o0, o1; float o, od, m;
  __m128i _o0, _o1, *_O0, *_O1; __m128 _o, _o0f, _m, *_M0, *_M1;
  // define useful constants
  const float oMult=(float)nOrients/PI; const int oMax=nOrients*nb;
  const __m128 _norm=SET(norm), _oMult=SET(oMult), _nbf=SET((float)nb);
  const __m128i _oMax=SET(oMax), _nb=SET(nb);
  // perform the majority of the work with sse
  _O0=(__m128i*) O0; _O1=(__m128i*) O1; _M0=(__m128*) M0; _M1=(__m128*) M1;
  for( i=0; i<=n-4; i+=4 ) {
    _o=MUL(LDu(O[i]),_oMult); _o0f=CVT(CVT(_o)); _o0=CVT(MUL(_o0f,_nbf));
    _o1=ADD(_o0,_nb); _o1=AND(CMPGT(_oMax,_o1),_o1);
    *_O0++=_o0; *_O1++=_o1; _m=MUL(LDu(M[i]),_norm);
    *_M1=MUL(SUB(_o,_o0f),_m); *_M0=SUB(_m,*_M1); _M0++; _M1++;
  }
  // compute trailing locations without sse
  for( i; i<n; i++ ) {
    o=O[i]*oMult; m=M[i]*norm; o0=(int) o; od=o-o0;
    o0*=nb; o1=o0+nb; if(o1==oMax) o1=0;
    O0[i]=o0; O1[i]=o1; M1[i]=od*m; M0[i]=m-M1[i];
  }
}
Beispiel #4
0
void UMeshAnimation::ConvertAnims()
{
	guard(UMeshAnimation::ConvertAnims);

	int i, j;

	CAnimSet *AnimSet = new CAnimSet(this);
	ConvertedAnim = AnimSet;

	// TrackBoneNames
	int numBones = RefBones.Num();
	AnimSet->TrackBoneNames.AddUninitialized(numBones);
	for (i = 0; i < numBones; i++)
		AnimSet->TrackBoneNames[i] = RefBones[i].Name;

	// Sequences
	int numSeqs = AnimSeqs.Num();
	AnimSet->Sequences.AddZeroed(numSeqs);
	for (i = 0; i < numSeqs; i++)
	{
		CAnimSequence &S = AnimSet->Sequences[i];
		const FMeshAnimSeq &Src = AnimSeqs[i];
		const MotionChunk  &M   = Moves[i];

		// attributes
		S.Name      = Src.Name;
		S.NumFrames = Src.NumFrames;
		S.Rate      = Src.Rate;

		// S.Tracks
		S.Tracks.AddZeroed(numBones);
		for (j = 0; j < numBones; j++)
		{
			CAnimTrack &T = S.Tracks[j];
			const AnalogTrack &A = M.AnimTracks[j];
			CopyArray(T.KeyPos,  CVT(A.KeyPos));
			CopyArray(T.KeyQuat, CVT(A.KeyQuat));
			CopyArray(T.KeyTime, A.KeyTime);
			// usually MotionChunk.TrackTime is identical to NumFrames, but some packages exists where
			// time channel should be adjusted
			if (M.TrackTime > 0)
			{
				float TimeScale = Src.NumFrames / M.TrackTime;
				for (int k = 0; k < T.KeyTime.Num(); k++)
					T.KeyTime[k] *= TimeScale;
			}
		}
	}

	unguard;
}
Beispiel #5
0
static void
cvtcmap(TIFFRGBAImage* img)
{
    uint16* r = img->redcmap;
    uint16* g = img->greencmap;
    uint16* b = img->bluecmap;
    long i;

    for (i = (1L<<img->bitspersample)-1; i >= 0; i--) {
#define CVT(x)      ((uint16)(((x) * 255) / ((1L<<16)-1)))
    r[i] = CVT(r[i]);
    g[i] = CVT(g[i]);
    b[i] = CVT(b[i]);
#undef  CVT
    }
}
Beispiel #6
0
static void
CheckAndCorrectColormap(TIFF* tif, int n, uint16* r, uint16* g, uint16* b)
{
	int i;

	for (i = 0; i < n; i++)
		if (r[i] >= 256 || g[i] >= 256 || b[i] >= 256)
			return;
	TIFFWarning(TIFFFileName(tif), "Scaling 8-bit colormap");
#define	CVT(x)		(((x) * ((1L<<16)-1)) / 255)
	for (i = 0; i < n; i++) {
		r[i] = CVT(r[i]);
		g[i] = CVT(g[i]);
		b[i] = CVT(b[i]);
	}
#undef CVT
}
Beispiel #7
0
// helper for gradHist, quantize O and M into O0, O1 and M0, M1 (uses sse)
void CPedestrianDetection::gradQuantize(float *O, float *M, int *O0, int *O1, float *M0, float *M1,
  int nb, int n, float norm, int nOrients, bool full, bool interpolate )
{
  // assumes all *OUTPUT* matrices are 4-byte aligned
  int i, o0, o1; float o, od, m;
  __m128i _o0, _o1, *_O0, *_O1; __m128 _o, _od, _m, *_M0, *_M1;
  // define useful constants
  const float oMult=(float)nOrients/(full?2*PI:PI); const int oMax=nOrients*nb;
  const __m128 _norm=SET(norm), _oMult=SET(oMult), _nbf=SET((float)nb);
  const __m128i _oMax=SET(oMax), _nb=SET(nb);
  // perform the majority of the work with sse
  _O0=(__m128i*) O0; _O1=(__m128i*) O1; _M0=(__m128*) M0; _M1=(__m128*) M1;
  if( interpolate ) for( i=0; i<=n-4; i+=4 ) {
    _o=MUL(LDu(O[i]),_oMult); _o0=CVT(_o); _od=SUB(_o,CVT(_o0));
    _o0=CVT(MUL(CVT(_o0),_nbf)); _o0=AND(CMPGT(_oMax,_o0),_o0); *_O0++=_o0;
    _o1=ADD(_o0,_nb); _o1=AND(CMPGT(_oMax,_o1),_o1); *_O1++=_o1;
    _m=MUL(LDu(M[i]),_norm); *_M1=MUL(_od,_m); *_M0++=SUB(_m,*_M1); _M1++;
  } else for( i=0; i<=n-4; i+=4 ) {
    _o=MUL(LDu(O[i]),_oMult); _o0=CVT(ADD(_o,SET(.5f)));
    _o0=CVT(MUL(CVT(_o0),_nbf)); _o0=AND(CMPGT(_oMax,_o0),_o0); *_O0++=_o0;
    *_M0++=MUL(LDu(M[i]),_norm); *_M1++=SET(0.f); *_O1++=SET(0);
  }
  // compute trailing locations without sse
  if( interpolate ) for(; i<n; i++ ) {
    o=O[i]*oMult; o0=(int) o; od=o-o0;
    o0*=nb; if(o0>=oMax) o0=0; O0[i]=o0;
    o1=o0+nb; if(o1==oMax) o1=0; O1[i]=o1;
    m=M[i]*norm; M1[i]=od*m; M0[i]=m-M1[i];
  } else for(; i<n; i++ ) {
    o=O[i]*oMult; o0=(int) (o+.5f);
    o0*=nb; if(o0>=oMax) o0=0; O0[i]=o0;
    M0[i]=M[i]*norm; M1[i]=0; O1[i]=0;
  }
}
uint8_t COL_YuvToRgb( uint8_t y,int8_t u,int8_t v,uint8_t *r,uint8_t *g,uint8_t *b)
{

	float rr,bb,gg;
	float yy=y,uu=u,vv=v;

	rr=	yy+			 	1.402*vv;
	gg= yy+ 	-0.344*uu+  	-0.714*vv;
	bb=	yy+ 	1.772*uu 	 		;

	#define CLIP(x) if(x>255) x=255; else if (x<0) x=0;x=x+0.49;
	#define CVT(x,y) CLIP(x);*y=(uint8_t)floor(x);

	CVT(rr,r);
	CVT(gg,g);
	CVT(bb,b);

	return 1;

}
Beispiel #9
0
/*
 *--Full format

            1         2         3         4         5         6         7
  01234567890123456789012345678901234567890123456789012345678901234567890123456789
  Sep  1  1990   - start with ' '
  Sep 11 11:59
  Sep 11 01:59   - start with 0
  Sep 11  1:59   - start with ' '
  Dec 12 1989
  FCv 23 1990

 *--Short format:

            1         2         3         4         5         6         7
  01234567890123456789012345678901234567890123456789012345678901234567890123456789
  f 01:07   - time
  f 01:7    - minutes with one digit
  F 15:43
  f  2002   - only year

 *--Expanded format:

            1         2         3         4         5         6         7
  01234567890123456789012345678901234567890123456789012345678901234567890123456789
 *2005-06-20 14:22
 *2005-07-08 19:21
 *2004-10-14 14:14
 *2004-10-14 14:14
*/
BOOL net_convert_unix_date(LPSTR& datestr, Time_t& decoded)
{
	SYSTEMTIME st;
	GetSystemTime(&st);
	st.wMilliseconds = 0;
	st.wSecond       = 0;
	st.wDayOfWeek    = 0;
	char *bcol = datestr;         /* Column begin */
	char *ecol;                   /* Column end */
	//Expanded format (DDDD-)
	if(NET_IS_DIGIT(bcol[0]) && NET_IS_DIGIT(bcol[1]) && NET_IS_DIGIT(bcol[2]) && NET_IS_DIGIT(bcol[3]) &&
	        bcol[4] == '-')
	{
#define CVT( nm, start, end )              bcol[end] = 0;                       \
	st.nm = atoi(bcol+start);   \
	CHECK( (st.nm == MAX_WORD), FALSE )
		CVT(wYear,   0,  4)
		CVT(wMonth,  5,  7)
		CVT(wDay,    8, 10)
		CVT(wHour,  11, 13)
		CVT(wMinute,14, 16)
#undef CVT
		datestr = bcol + 17;
		return SystemTimeToFileTime(&st, decoded);
	}

	//Month+day or short format
	// (ecol must be set to char after decoded part)
	if(NET_TO_UPPER(bcol[0]) == 'F' &&
	        NET_IS_SPACE(bcol[1]))
	{
		//Short format - ignore month and day
		ecol = bcol + 2;
	}
	else
	{
		//Month
		if(NET_IS_DIGIT(bcol[0]) && NET_IS_DIGIT(bcol[1]) && NET_IS_SPACE(bcol[2]))
			st.wMonth = AtoI(bcol,MAX_WORD);
		else
			st.wMonth = NET_MonthNo(datestr);

		CHECK((st.wMonth == MAX_WORD), FALSE)
		bcol = SkipSpace(SkipNSpace(bcol));
		CHECK((*bcol == 0), FALSE)
		//Day
		ecol = SkipNSpace(bcol);

		if(*ecol != ' ')
			return FALSE;

		*ecol = 0;
		st.wDay = AtoI(bcol,MAX_WORD);
		*ecol = ' ';
		CHECK((st.wDay == MAX_WORD), FALSE)
	}

	//Year or time
	ecol = SkipSpace(ecol);
	bcol = ecol;

	if(bcol[2] != ':' && bcol[1] != ':')
	{
		//Four digits year
		ecol = SkipDigit(bcol);
		CHECK((ecol == bcol), FALSE)
		*ecol = 0;
		st.wYear = AtoI(bcol,MAX_WORD);
		ecol++;
		CHECK((st.wYear == MAX_WORD), FALSE)

		//Only first three digits of year with cut last digit
		if(st.wYear > 190 && st.wYear < 300)
		{
			st.wYear *= 10;
		}

		st.wSecond = 0;
		st.wMinute = 0;
		st.wHour   = 0;
	}
Beispiel #10
0
	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;
					}
				}
Beispiel #11
0
void PLTIFFDecoder::doLoColor (TIFF * tif, PLBmpBase * pBmp)
{
  uint16  BitsPerSample;
  uint16  SamplePerPixel;
  int32  LineSize;
  int16  PhotometricInterpretation;
  int  row;
  PLBYTE  *pBits;

  TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &BitsPerSample);
  TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &SamplePerPixel);
  TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &PhotometricInterpretation);

  if (PhotometricInterpretation!=PHOTOMETRIC_MINISWHITE &&
      PhotometricInterpretation!=PHOTOMETRIC_MINISBLACK &&
      PhotometricInterpretation!=PHOTOMETRIC_PALETTE)
  {
    PhotometricInterpretation = PHOTOMETRIC_MINISWHITE;
    Trace(2,"unexpected PhotometricInterpretation, default to PHOTOMETRIC_MINISWHITE");
  }

  LineSize = TIFFScanlineSize(tif); //Number of bytes in one line

  PLPixel32 pPal[256];

  pBits = new PLBYTE [LineSize]; // enough for 16-bits per pixel
  if (pBits == NULL)
    raiseError (PL_ERRNO_MEMORY, "Out of memory allocating TIFF buffer.");

  // phase one: build color map
  if (BitsPerSample < 16) {
    if /* monochrome (=bitonal) or grayscale */
      (PhotometricInterpretation == PHOTOMETRIC_MINISWHITE ||
       PhotometricInterpretation == PHOTOMETRIC_MINISBLACK)
      {
        int numColors = 1 << BitsPerSample;
        PLBYTE step = static_cast<PLBYTE>(255 / (numColors-1));
        PLBYTE *pb = (PLBYTE *) (pPal);
        int offset = sizeof(PLPixel32);
        if (PhotometricInterpretation == PHOTOMETRIC_MINISWHITE)
        {
          pb += (numColors-1) * sizeof(PLPixel32);
          offset = -offset;
        }
        // warning: the following ignores possible halftone hints
        for (int i = 0; i < numColors; ++i, pb += offset)
        {
          pb[PL_RGBA_RED] = pb[PL_RGBA_GREEN] = pb[PL_RGBA_BLUE] = static_cast<PLBYTE>(i * step);
          pb[PL_RGBA_ALPHA] = 255;
        }

      }
    //PhotometricInterpretation = 2 image is RGB
    //PhotometricInterpretation = 3 image has a color palette
    else if (PhotometricInterpretation == PHOTOMETRIC_PALETTE)
    {
      uint16* red;
      uint16* green;
      uint16* blue;
      int16 Palette16Bits;

      // we get pointers to libtiff-owned colormaps
      TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue);

      //Is the palette 16 or 8 bits ?
      Palette16Bits = checkcmap(1<<BitsPerSample, red, green, blue) == 16;

      //load the palette in the DIB
      for (int i = 0; i < 1<<BitsPerSample; ++i)
      {
        PLBYTE *pb = (PLBYTE *) ((pPal)+i);
        pb[PL_RGBA_RED  ] = (PLBYTE) (Palette16Bits ? CVT(  red[i]) :   red[i]);
        pb[PL_RGBA_GREEN] = (PLBYTE) (Palette16Bits ? CVT(green[i]) : green[i]);
        pb[PL_RGBA_BLUE ] = (PLBYTE) (Palette16Bits ? CVT( blue[i]) :  blue[i]);
        pb[PL_RGBA_ALPHA] = 255;
      }
    }
    else
      Trace( 2, "unexpected PhotometricInterpretation in PLTIFFDecoder::DoLoColor()" );
  }
  // phase two: read image itself

  //generally, TIFF images are ordered from upper-left to bottom-right
  // we implicitly assume PLANARCONFIG_CONTIG
  PLBYTE **pLineArray = pBmp->GetLineArray();  

  if (BitsPerSample > 16)
    Trace( 2, "unexpected bit-depth in PLTIFFDecoder::DoLoColor()" );
  else for ( row = 0; row < GetHeight(); ++row )
    {
      uint16 x;
      int status = TIFFReadScanline( tif, pBits, row, 0 );
      if (status == -1 && row < GetHeight()  / 3)
      {
        delete [] pBits;
        // we should maybe free the BMP memory as well...
        raiseError (PL_ERRINTERNAL, m_szLastErr);
      }
      /*
      if (BitsPerSample == 1)  // go ahead, waste space ;-)
        for (x=0; x < imageWidth; ++x)
          pLineArray[row][x] = pBits[x / 8] & (128 >> (x & 7)) ? 1 : 0;
      else */
      if (BitsPerSample == 4)
      {
        for (x=0; x < GetWidth() / 2; ++x)
        {
          pLineArray[row][2*x  ] = (pBits[x] & 0xf0) >> 4;
          pLineArray[row][2*x+1] = (pBits[x] & 0x0f);
        }
        // odd number of pixels
        if (GetWidth() & 1)
          pLineArray[row][GetWidth()-1] = (pBits[x] & 0xf0) >> 4;
      } else if (BitsPerSample == 16) {
          PLASSERT (SamplePerPixel == 1); // can't do 16-bit with alpha yet
          PLPixel16 **pLineArray16 = pBmp->GetLineArray16();
          memcpy( pLineArray16[row], pBits, LineSize );
      } else //if (BitsPerSample == 8 || BitsPerSample == 1)
        if (SamplePerPixel == 1)
          memcpy( pLineArray[row], pBits, LineSize );
        else
        {
          // We've got an 8 bit image with an alpha channel.
          // Ignore the alpha channel.
          PLASSERT (BitsPerSample == 8);
          for (x=0; x < GetWidth(); ++x)
            pLineArray[row][x] = pBits[x*2];
        }
    }
Beispiel #12
0
void
PSDataPalette(FILE* fd, TIFF* tif, uint32 w, uint32 h)
{
	uint16 *rmap, *gmap, *bmap;
	uint32 row;
	int breaklen = MAXLINE, cc, nc;
	unsigned char *tf_buf;
	unsigned char *cp, c;

	(void) w;
	if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) {
		TIFFError(filename, "Palette image w/o \"Colormap\" tag");
		return;
	}
	switch (bitspersample) {
	case 8:	case 4: case 2: case 1:
		break;
	default:
		TIFFError(filename, "Depth %d not supported", bitspersample);
		return;
	}
	nc = 3 * (8 / bitspersample);
	tf_buf = (unsigned char *) _TIFFmalloc(tf_bytesperrow);
	if (tf_buf == NULL) {
		TIFFError(filename, "No space for scanline buffer");
		return;
	}
	if (checkcmap(tif, 1<<bitspersample, rmap, gmap, bmap) == 16) {
		int i;
#define	CVT(x)		(((x) * 255) / ((1U<<16)-1))
		for (i = (1<<bitspersample)-1; i >= 0; i--) {
			rmap[i] = CVT(rmap[i]);
			gmap[i] = CVT(gmap[i]);
			bmap[i] = CVT(bmap[i]);
		}
#undef CVT
	}
	for (row = 0; row < h; row++) {
		if (TIFFReadScanline(tif, tf_buf, row, 0) < 0)
			break;
		for (cp = tf_buf, cc = 0; cc < tf_bytesperrow; cc++) {
			DOBREAK(breaklen, nc, fd);
			switch (bitspersample) {
			case 8:
				c = *cp++; PUTRGBHEX(c, fd);
				break;
			case 4:
				c = *cp++; PUTRGBHEX(c&0xf, fd);
				c >>= 4;   PUTRGBHEX(c, fd);
				break;
			case 2:
				c = *cp++; PUTRGBHEX(c&0x3, fd);
				c >>= 2;   PUTRGBHEX(c&0x3, fd);
				c >>= 2;   PUTRGBHEX(c&0x3, fd);
				c >>= 2;   PUTRGBHEX(c, fd);
				break;
			case 1:
				c = *cp++; PUTRGBHEX(c&0x1, fd);
				c >>= 1;   PUTRGBHEX(c&0x1, fd);
				c >>= 1;   PUTRGBHEX(c&0x1, fd);
				c >>= 1;   PUTRGBHEX(c&0x1, fd);
				c >>= 1;   PUTRGBHEX(c&0x1, fd);
				c >>= 1;   PUTRGBHEX(c&0x1, fd);
				c >>= 1;   PUTRGBHEX(c&0x1, fd);
				c >>= 1;   PUTRGBHEX(c, fd);
				break;
			}
		}
	}
	_TIFFfree((char *) tf_buf);
}
Beispiel #13
0
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;
}
Beispiel #14
0
void CVertMeshInstance::SetMesh(const UVertMesh *Mesh)
{
	pMesh = Mesh;
	SetAxis(Mesh->RotOrigin, BaseTransform.axis);
	BaseTransform.origin[0] = Mesh->MeshOrigin.X * Mesh->MeshScale.X;
	BaseTransform.origin[1] = Mesh->MeshOrigin.Y * Mesh->MeshScale.Y;
	BaseTransform.origin[2] = Mesh->MeshOrigin.Z * Mesh->MeshScale.Z;

	BaseTransformScaled.axis = BaseTransform.axis;
	CVec3 tmp;
	tmp[0] = 1.0f / Mesh->MeshScale.X;
	tmp[1] = 1.0f / Mesh->MeshScale.Y;
	tmp[2] = 1.0f / Mesh->MeshScale.Z;
	BaseTransformScaled.axis.PrescaleSource(tmp);
	BaseTransformScaled.origin = CVT(Mesh->MeshOrigin);

	FreeRenderBuffers();
	if (!pMesh->Faces.Num()) return;

	// prepare vertex and index buffers, build sections

	Verts   = new CVec3[pMesh->Wedges.Num()];
	Normals = new CVec3[pMesh->Wedges.Num()];
	Indices = new word[pMesh->Faces.Num() * 3];

	const FMeshFace *F = &pMesh->Faces[0];
	word *pIndex = Indices;
	int PrevMaterial = -2;
	CMeshSection *Sec = NULL;
	for (int i = 0; i < pMesh->Faces.Num(); i++, F++)
	{
		if (F->MaterialIndex != PrevMaterial)
		{
			// get material parameters
			int PolyFlags = 0;
			int TexIndex = 1000000;
			if (F->MaterialIndex < pMesh->Materials.Num())
			{
				const FMeshMaterial &M = pMesh->Materials[F->MaterialIndex];
				TexIndex  = M.TextureIndex;
				PolyFlags = M.PolyFlags;
			}
			// possible situation: Textures array is empty (mesh textured by script)
			UUnrealMaterial *Mat = (TexIndex < pMesh->Textures.Num()) ? MATERIAL_CAST(pMesh->Textures[TexIndex]) : NULL;

			// create new section
			Sec = new (Sections) CMeshSection;
			Sec->FirstIndex = pIndex - Indices;
			Sec->NumFaces   = 0;
			Sec->Material   = UMaterialWithPolyFlags::Create(Mat, PolyFlags);

			PrevMaterial = F->MaterialIndex;
		}
		// store indices
		// note: skeletal mesh and vertex mesh has opposite triangle vertex order
		*pIndex++ = F->iWedge[0];
		*pIndex++ = F->iWedge[2];
		*pIndex++ = F->iWedge[1];
		Sec->NumFaces++;
	}
}
Beispiel #15
0
void USkeletalMesh::ConvertMesh()
{
	guard(USkeletalMesh::ConvertMesh);

	CSkeletalMesh *Mesh = new CSkeletalMesh(this);
	ConvertedMesh = Mesh;
	Mesh->BoundingBox    = BoundingBox;
	Mesh->BoundingSphere = BoundingSphere;

	Mesh->RotOrigin  = RotOrigin;
	Mesh->MeshScale  = CVT(MeshScale);
	Mesh->MeshOrigin = CVT(MeshOrigin);

	Mesh->Lods.Empty(LODModels.Num());

#if DEBUG_SKELMESH
	appPrintf("  Base : Points[%d] Wedges[%d] Influences[%d] Faces[%d]\n",
		Points.Num(), Wedges.Num(), VertInfluences.Num(), Triangles.Num()
	);
#endif

	// some games has troubles with LOD models ...
#if TRIBES3
	if (GetGame() == GAME_Tribes3) goto base_mesh;
#endif
#if SWRC
	if (GetGame() == GAME_RepCommando) goto base_mesh;
#endif

	if (!LODModels.Num())
	{
	base_mesh:
		guard(ConvertBaseMesh);

		// create CSkelMeshLod from base mesh
		CSkelMeshLod *Lod = new (Mesh->Lods) CSkelMeshLod;
		Lod->NumTexCoords = 1;
		Lod->HasNormals   = false;
		Lod->HasTangents  = false;

		if (Points.Num() && Wedges.Num() && VertInfluences.Num())
		{
			InitSections(*Lod);
			ConvertWedges(*Lod, Points, Wedges, VertInfluences);
			BuildIndices(*Lod);
		}
		else
		{
			appPrintf("ERROR: bad base mesh\n");
		}
		goto skeleton;

		unguard;
	}

	// convert LODs
	for (int lod = 0; lod < LODModels.Num(); lod++)
	{
		guard(ConvertLod);

		const FStaticLODModel &SrcLod = LODModels[lod];

#if DEBUG_SKELMESH
		appPrintf("  Lod %d: Points[%d] Wedges[%d] Influences[%d] Faces[%d]  Rigid(Indices[%d] Verts[%d])  Smooth(Indices[%d] Verts[%d] Stream[%d])\n",
			lod, SrcLod.Points.Num(), SrcLod.Wedges.Num(), SrcLod.VertInfluences.Num(), SrcLod.Faces.Num(),
			SrcLod.RigidIndices.Indices.Num(), SrcLod.VertexStream.Verts.Num(),
			SrcLod.SmoothIndices.Indices.Num(), SrcLod.SkinPoints.Num(), SrcLod.SkinningData.Num()
		);
#endif
//		if (SrcLod.Faces.Num() == 0 && SrcLod.SmoothSections.Num() > 0)
//			continue;

		CSkelMeshLod *Lod = new (Mesh->Lods) CSkelMeshLod;
		Lod->NumTexCoords = 1;
		Lod->HasNormals   = false;
		Lod->HasTangents  = false;

		if (IsCorrectLOD(SrcLod))
		{
			InitSections(*Lod);
			ConvertWedges(*Lod, SrcLod.Points, SrcLod.Wedges, SrcLod.VertInfluences);
			BuildIndicesForLod(*Lod, SrcLod);
		}
		else
		{
			appPrintf("WARNING: bad LOD#%d mesh, switching to base\n", lod);
			if (lod == 0)
			{
				Mesh->Lods.Empty();
				goto base_mesh;
			}
			else
			{
				Mesh->Lods.RemoveAt(lod);
				break;
			}
		}

		unguard;
	}

skeleton:
	// copy skeleton
	guard(ProcessSkeleton);
	Mesh->RefSkeleton.Empty(RefSkeleton.Num());
	for (int i = 0; i < RefSkeleton.Num(); i++)
	{
		const FMeshBone &B = RefSkeleton[i];
		CSkelMeshBone *Dst = new (Mesh->RefSkeleton) CSkelMeshBone;
		Dst->Name        = B.Name;
		Dst->ParentIndex = B.ParentIndex;
		Dst->Position    = CVT(B.BonePos.Position);
		Dst->Orientation = CVT(B.BonePos.Orientation);
	}
	unguard; // ProcessSkeleton

	// copy sockets
	int NumSockets = AttachAliases.Num();
	Mesh->Sockets.Empty(NumSockets);
	for (int i = 0; i < NumSockets; i++)
	{
		CSkelMeshSocket *DS = new (Mesh->Sockets) CSkelMeshSocket;
		DS->Name      = AttachAliases[i];
		DS->Bone      = AttachBoneNames[i];
		DS->Transform = CVT(AttachCoords[i]);
	}

	Mesh->FinalizeMesh();

	unguard;
}
Beispiel #16
0
int
main(int argc, char* argv[])
{
    uint16 bitspersample, shortv;
    uint32 imagewidth, imagelength;
    uint16 config = PLANARCONFIG_CONTIG;
    uint32 rowsperstrip = (uint32) -1;
    uint16 photometric = PHOTOMETRIC_RGB;
    uint16 *rmap, *gmap, *bmap;
    uint32 row;
    int cmap = -1;
    TIFF *in, *out;
    int c;
    extern int optind;
    extern char* optarg;

    while ((c = getopt(argc, argv, "C:c:p:r:")) != -1)
        switch (c) {
        case 'C':		/* force colormap interpretation */
            cmap = atoi(optarg);
            break;
        case 'c':		/* compression scheme */
            if (!processCompressOptions(optarg))
                usage();
            break;
        case 'p':		/* planar configuration */
            if (streq(optarg, "separate"))
                config = PLANARCONFIG_SEPARATE;
            else if (streq(optarg, "contig"))
                config = PLANARCONFIG_CONTIG;
            else
                usage();
            break;
        case 'r':		/* rows/strip */
            rowsperstrip = atoi(optarg);
            break;
        case '?':
            usage();
            /*NOTREACHED*/
        }
    if (argc - optind != 2)
        usage();
    in = TIFFOpen(argv[optind], "r");
    if (in == NULL)
        return (-1);
    if (!TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &shortv) ||
            shortv != PHOTOMETRIC_PALETTE) {
        fprintf(stderr, "%s: Expecting a palette image.\n",
                argv[optind]);
        return (-1);
    }
    if (!TIFFGetField(in, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) {
        fprintf(stderr,
                "%s: No colormap (not a valid palette image).\n",
                argv[optind]);
        return (-1);
    }
    bitspersample = 0;
    TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample);
    if (bitspersample != 8) {
        fprintf(stderr, "%s: Sorry, can only handle 8-bit images.\n",
                argv[optind]);
        return (-1);
    }
    out = TIFFOpen(argv[optind+1], "w");
    if (out == NULL)
        return (-2);
    cpTags(in, out);
    TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &imagewidth);
    TIFFGetField(in, TIFFTAG_IMAGELENGTH, &imagelength);
    if (compression != (uint16)-1)
        TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
    else
        TIFFGetField(in, TIFFTAG_COMPRESSION, &compression);
    switch (compression) {
    case COMPRESSION_JPEG:
        if (jpegcolormode == JPEGCOLORMODE_RGB)
            photometric = PHOTOMETRIC_YCBCR;
        else
            photometric = PHOTOMETRIC_RGB;
        TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
        TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
        break;
    case COMPRESSION_LZW:
    case COMPRESSION_DEFLATE:
        if (predictor != 0)
            TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
        break;
    }
    TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
    TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 3);
    TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
    TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
                 rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip));
    (void) TIFFGetField(in, TIFFTAG_PLANARCONFIG, &shortv);
    if (cmap == -1)
        cmap = checkcmap(1<<bitspersample, rmap, gmap, bmap);
    if (cmap == 16) {
        /*
         * Convert 16-bit colormap to 8-bit.
         */
        int i;

        for (i = (1<<bitspersample)-1; i >= 0; i--) {
#define	CVT(x)		(((x) * 255) / ((1L<<16)-1))
            rmap[i] = CVT(rmap[i]);
            gmap[i] = CVT(gmap[i]);
            bmap[i] = CVT(bmap[i]);
        }
    }
    {   unsigned char *ibuf, *obuf;
        register unsigned char* pp;
        register uint32 x;
        ibuf = (unsigned char*)_TIFFmalloc(TIFFScanlineSize(in));
        obuf = (unsigned char*)_TIFFmalloc(TIFFScanlineSize(out));
        switch (config) {
        case PLANARCONFIG_CONTIG:
            for (row = 0; row < imagelength; row++) {
                if (!TIFFReadScanline(in, ibuf, row, 0))
                    goto done;
                pp = obuf;
                for (x = 0; x < imagewidth; x++) {
                    *pp++ = rmap[ibuf[x]];
                    *pp++ = gmap[ibuf[x]];
                    *pp++ = bmap[ibuf[x]];
                }
                if (!TIFFWriteScanline(out, obuf, row, 0))
                    goto done;
            }
            break;
        case PLANARCONFIG_SEPARATE:
            for (row = 0; row < imagelength; row++) {
                if (!TIFFReadScanline(in, ibuf, row, 0))
                    goto done;
                for (pp = obuf, x = 0; x < imagewidth; x++)
                    *pp++ = rmap[ibuf[x]];
                if (!TIFFWriteScanline(out, obuf, row, 0))
                    goto done;
                for (pp = obuf, x = 0; x < imagewidth; x++)
                    *pp++ = gmap[ibuf[x]];
                if (!TIFFWriteScanline(out, obuf, row, 0))
                    goto done;
                for (pp = obuf, x = 0; x < imagewidth; x++)
                    *pp++ = bmap[ibuf[x]];
                if (!TIFFWriteScanline(out, obuf, row, 0))
                    goto done;
            }
            break;
        }
        _TIFFfree(ibuf);
        _TIFFfree(obuf);
    }
done:
    (void) TIFFClose(in);
    (void) TIFFClose(out);
    return (0);
}
Beispiel #17
0
// Returns false if the output value is not the same as the number's value, which
//  can occur due to accuracy loss and the value not being within the target range.
static Boolean __CFNumberGetValue(CFNumberRef number, CFNumberType type, void* valuePtr) {

    #define CVT(SRC_TYPE, DST_TYPE, DST_MIN, DST_MAX) \
        do { \
            SRC_TYPE sv; \
            memmove(&sv, data, sizeof(SRC_TYPE)); \
            DST_TYPE dv = (sv < DST_MIN) ? \
                (DST_TYPE)(DST_MIN) : \
                (DST_TYPE)((DST_MAX < sv) ? DST_MAX : sv); \
            memmove(valuePtr, &dv, sizeof(DST_TYPE)); \
            SRC_TYPE vv = (SRC_TYPE)dv; \
            return (vv == sv); \
        } while (0)

    #define CVT128ToInt(SRC_TYPE, DST_TYPE, DST_MIN, DST_MAX) \
        do { \
            SRC_TYPE sv; \
            memmove(&sv, data, sizeof(SRC_TYPE)); \
            DST_TYPE dv; Boolean noLoss = false; \
            if (0 < sv.high || (!sv.high && (int64_t)DST_MAX < sv.low)) { \
                dv = DST_MAX; \
            } else if (sv.high < -1 || (-1 == sv.high && sv.low < (int64_t)DST_MIN)) { \
                dv = DST_MIN; \
            } else { \
                dv = (DST_TYPE)sv.low; \
                noLoss = true; \
            } \
            memmove(valuePtr, &dv, sizeof(DST_TYPE)); \
            return noLoss; \
        } while (0)

    /*****/

    type = __CFNumberTypeTable[type].canonicalType;
    CFNumberType ntype = __CFNumberGetType(number);
    const void* data = &(number->_pad);
    switch (type) {
        case kCFNumberSInt8Type:
            if (__CFNumberTypeTable[ntype].floatBit) {
                if (!__CFNumberTypeTable[ntype].storageBit) {
                    CVT(Float32, int8_t, INT8_MIN, INT8_MAX);
                } else {
                    CVT(Float64, int8_t, INT8_MIN, INT8_MAX);
                }
            } else {
                if (!__CFNumberTypeTable[ntype].storageBit) {
                    CVT(int64_t, int8_t, INT8_MIN, INT8_MAX);
                } else {
                    CVT128ToInt(CFSInt128Struct, int8_t, INT8_MIN, INT8_MAX);
                }
            }
            return true;
        case kCFNumberSInt16Type:
            if (__CFNumberTypeTable[ntype].floatBit) {
                if (!__CFNumberTypeTable[ntype].storageBit) {
                    CVT(Float32, int16_t, INT16_MIN, INT16_MAX);
                } else {
                    CVT(Float64, int16_t, INT16_MIN, INT16_MAX);
                }
            } else {
                if (!__CFNumberTypeTable[ntype].storageBit) {
                    CVT(int64_t, int16_t, INT16_MIN, INT16_MAX);
                } else {
                    CVT128ToInt(CFSInt128Struct, int16_t, INT16_MIN, INT16_MAX);
                }
            }
            return true;
        case kCFNumberSInt32Type:
            if (__CFNumberTypeTable[ntype].floatBit) {
                if (!__CFNumberTypeTable[ntype].storageBit) {
                    CVT(Float32, int32_t, INT32_MIN, INT32_MAX);
                } else {
                    CVT(Float64, int32_t, INT32_MIN, INT32_MAX);
                }
            } else {
                if (!__CFNumberTypeTable[ntype].storageBit) {
                    CVT(int64_t, int32_t, INT32_MIN, INT32_MAX);
                } else {
                    CVT128ToInt(CFSInt128Struct, int32_t, INT32_MIN, INT32_MAX);
                }
            }
            return true;
        case kCFNumberSInt64Type:
            if (__CFNumberTypeTable[ntype].floatBit) {
                if (!__CFNumberTypeTable[ntype].storageBit) {
                    CVT(Float32, int64_t, INT64_MIN, INT64_MAX);
                } else {
                    CVT(Float64, int64_t, INT64_MIN, INT64_MAX);
                }
            } else {
                if (!__CFNumberTypeTable[ntype].storageBit) {
                    memmove(valuePtr, data, 8);
                } else {
                    CVT128ToInt(CFSInt128Struct, int64_t, INT64_MIN, INT64_MAX);
                }
            }
            return true;
        case kCFNumberSInt128Type:
            if (__CFNumberTypeTable[ntype].floatBit) {
                if (!__CFNumberTypeTable[ntype].storageBit) {
                    Float32 f;
                    memmove(&f, data, 4);
                    Float64 d = f;
                    CFSInt128Struct i;
                    __CFSInt128FromFloat64(&i, &d);
                    memmove(valuePtr, &i, 16);
                    Float64 d2;
                    __CFSInt128ToFloat64(&d2, &i);
                    Float32 f2 = (Float32)d2;
                    return (f2 == f);
                } else {
                    Float64 d;
                    memmove(&d, data, 8);
                    CFSInt128Struct i;
                    __CFSInt128FromFloat64(&i, &d);
                    memmove(valuePtr, &i, 16);
                    Float64 d2;
                    __CFSInt128ToFloat64(&d2, &i);
                    return (d2 == d);
                }
            } else {
                if (!__CFNumberTypeTable[ntype].storageBit) {
                    int64_t j;
                    memmove(&j, data, 8);
                    CFSInt128Struct i;
                    i.low = j;
                    i.high = (j < 0) ? -1LL : 0LL;
                    memmove(valuePtr, &i, 16);
                } else {
                    memmove(valuePtr, data, 16);
                }
            }
            return true;
        case kCFNumberFloat32Type:
            if (__CFNumberTypeTable[ntype].floatBit) {
                if (!__CFNumberTypeTable[ntype].storageBit) {
                    memmove(valuePtr, data, 4);
                } else {
                    double d;
                    memmove(&d, data, 8);
                    if (isnan(d)) {
                        uint32_t l = 0x7fc00000;
                        memmove(valuePtr, &l, 4);
                        return true;
                    } else if (isinf(d)) {
                        uint32_t l = 0x7f800000;
                        if (d < 0.0) {
                            l += 0x80000000UL;
                        }
                        memmove(valuePtr, &l, 4);
                        return true;
                    }
                    CVT(Float64, Float32, -FLT_MAX, FLT_MAX);
                }
            } else {
                if (!__CFNumberTypeTable[ntype].storageBit) {
                    CVT(int64_t, Float32, -FLT_MAX, FLT_MAX);
                } else {
                    CFSInt128Struct i;
                    memmove(&i, data, 16);
                    Float64 d;
                    __CFSInt128ToFloat64(&d, &i);
                    Float32 f = (Float32)d;
                    memmove(valuePtr, &f, 4);
                    d = f;
                    CFSInt128Struct i2;
                    __CFSInt128FromFloat64(&i2, &d);
                    return __CFSInt128Compare(&i2, &i) == kCFCompareEqualTo;
                }
            }
            return true;
        case kCFNumberFloat64Type:
            if (__CFNumberTypeTable[ntype].floatBit) {
                if (!__CFNumberTypeTable[ntype].storageBit) {
                    float f;
                    memmove(&f, data, 4);
                    if (isnan(f)) {
                        uint64_t l = DOUBLE_NAN_BITS;
                        memmove(valuePtr, &l, 8);
                        return true;
                    } else if (isinf(f)) {
                        uint64_t l = DOUBLE_POSINF_BITS;
                        if (f < 0.0) {
                            l += 0x8000000000000000ULL;
                        }
                        memmove(valuePtr, &l, 8);
                        return true;
                    }
                    CVT(Float32, Float64, -DBL_MAX, DBL_MAX);
                } else {
                    memmove(valuePtr, data, 8);
                }
            } else {
                if (!__CFNumberTypeTable[ntype].storageBit) {
                    CVT(int64_t, Float64, -DBL_MAX, DBL_MAX);
                } else {
                    CFSInt128Struct i;
                    memmove(&i, data, 16);
                    Float64 d;
                    __CFSInt128ToFloat64(&d, &i);
                    memmove(valuePtr, &d, 8);
                    CFSInt128Struct i2;
                    __CFSInt128FromFloat64(&i2, &d);
                    return __CFSInt128Compare(&i2, &i) == kCFCompareEqualTo;
                }
            }
            return true;
    }
    return false;

    /*****/

    #undef CVT
    #undef CVT128ToInt
}
Beispiel #18
0
void USkelModel::Serialize(FArchive &Ar)
{
	guard(USkelModel::Serialize);

	assert(Ar.IsLoading);					// no saving ...
	Super::Serialize(Ar);

	// USkelModel data
	int nummeshes;
	int numjoints;
	int numframes;
	int numsequences;
	int numskins;
	int rootjoint;

	FVector					PosOffset;		// Offset of creature relative to base
	FRotator				RotOffset;		// Offset of creatures rotation

	TArray<RMesh>			meshes;
	TArray<RJoint>			joints;
	TArray<FRSkelAnimSeq>	AnimSeqs;		// Compressed animation data for sequence
	TArray<RAnimFrame>		frames;

	Ar << nummeshes << numjoints << numframes << numsequences << numskins << rootjoint;
	Ar << meshes << joints << AnimSeqs << frames << PosOffset << RotOffset;

	int modelIdx;
	// create all meshes first, then fill them (for better view order)
	for (modelIdx = 0; modelIdx < meshes.Num(); modelIdx++)
	{
		// create new USkeletalMesh
		// use "CreateClass()" instead of "new USkeletalMesh" to allow this object to be
		// placed in GObjObjects array and be browsable in a viewer
		USkeletalMesh *sm = static_cast<USkeletalMesh*>(CreateClass("SkeletalMesh"));
		char nameBuf[256];
		appSprintf(ARRAY_ARG(nameBuf), "%s_%d", Name, modelIdx);
		const char *name = appStrdupPool(nameBuf);
		Meshes.Add(sm);
		// setup UOnject
		sm->Name         = name;
		sm->Package      = Package;
		sm->PackageIndex = INDEX_NONE;		// not really exported
		sm->Outer        = NULL;
	}
	// create animation
	Anim = static_cast<UMeshAnimation*>(CreateClass("MeshAnimation"));
	Anim->Name         = Name;
	Anim->Package      = Package;
	Anim->PackageIndex = INDEX_NONE;		// not really exported
	Anim->Outer        = NULL;
	ConvertRuneAnimations(*Anim, joints, AnimSeqs);
	Anim->ConvertAnims();					//?? second conversion
	// get baseframe
	assert(strcmp(Anim->AnimSeqs[0].Name, "baseframe") == 0);
	const TArray<AnalogTrack> &BaseAnim = Anim->Moves[0].AnimTracks;
	// compute bone coordinates
	TArray<CCoords> BoneCoords;
	BuildSkeleton(BoneCoords, joints, BaseAnim);

	// setup meshes
	for (modelIdx = 0; modelIdx < meshes.Num(); modelIdx++)
	{
		int i, j;
		const RMesh  &src = meshes[modelIdx];
		USkeletalMesh *sm = Meshes[modelIdx];
		sm->Animation = Anim;
		// setup ULodMesh
		sm->RotOrigin = RotOffset;
		sm->MeshScale.Set(1, 1, 1);
		sm->MeshOrigin = PosOffset;
		// copy skeleton
		sm->RefSkeleton.Empty(joints.Num());
		for (i = 0; i < joints.Num(); i++)
		{
			const RJoint &J = joints[i];
			FMeshBone *B = new(sm->RefSkeleton) FMeshBone;
			B->Name = J.name;
			B->Flags = 0;
			B->ParentIndex = (J.parent > 0) ? J.parent : 0;		// -1 -> 0
			// copy bone orientations from base animation frame
			B->BonePos.Orientation = BaseAnim[i].KeyQuat[0];
			B->BonePos.Position    = BaseAnim[i].KeyPos[0];
		}
		// copy vertices
		int VertexCount = sm->VertexCount = src.verts.Num();
		sm->Points.Empty(VertexCount);
		for (i = 0; i < VertexCount; i++)
		{
			const RVertex &v1 = src.verts[i];
			FVector *V = new(sm->Points) FVector;
			// transform point from local bone space to model space
			BoneCoords[v1.joint1].UnTransformPoint(CVT(v1.point1), CVT(*V));
		}
		// copy triangles and create wedges
		// here we create 3 wedges for each triangle.
		// it is possible to reduce number of wedges by finding duplicates, but we don't
		// need it here ...
		int TrisCount = src.tris.Num();
		sm->Triangles.Empty(TrisCount);
		sm->Wedges.Empty(TrisCount * 3);
		int numMaterials = 0;		// should detect real material count
		for (i = 0; i < TrisCount; i++)
		{
			const RTriangle &tri = src.tris[i];
			// create triangle
			VTriangle *T = new(sm->Triangles) VTriangle;
			T->MatIndex = tri.polygroup;
			if (numMaterials <= tri.polygroup)
				numMaterials = tri.polygroup+1;
			// create wedges
			for (j = 0; j < 3; j++)
			{
				T->WedgeIndex[j] = sm->Wedges.Num();
				FMeshWedge *W = new(sm->Wedges) FMeshWedge;
				W->iVertex = tri.vIndex[j];
				W->TexUV   = tri.tex[j];
			}
			// reverse order of triangle vertices
			Exchange(T->WedgeIndex[0], T->WedgeIndex[1]);
		}
		// build influences
		for (i = 0; i < VertexCount; i++)
		{
			const RVertex &v1 = src.verts[i];
			FVertInfluence *Inf = new(sm->VertInfluences) FVertInfluence;
			Inf->PointIndex = i;
			Inf->BoneIndex  = v1.joint1;
			Inf->Weight     = v1.weight1;
			if (Inf->Weight != 1.0f)
			{
				// influence for 2nd bone
				Inf = new(sm->VertInfluences) FVertInfluence;
				Inf->PointIndex = i;
				Inf->BoneIndex  = v1.joint2;
				Inf->Weight     = 1.0f - v1.weight1;
			}
		}
		// create materials
		for (i = 0; i < numMaterials; i++)
		{
			const char *texName = src.PolyGroupSkinNames[i];
			FMeshMaterial *M1 = new(sm->Materials) FMeshMaterial;
			M1->PolyFlags    = src.GroupFlags[i];
			M1->TextureIndex = sm->Textures.Num();
			if (strcmp(texName, "None") == 0)
			{
				// texture should be set from script
				sm->Textures.Add(NULL);
				continue;
			}
			// find texture in object's package
			int texExportIdx = Package->FindExport(texName);
			if (texExportIdx == INDEX_NONE)
			{
				appPrintf("ERROR: unable to find export \"%s\" for mesh \"%s\" (%d)\n",
					texName, Name, modelIdx);
				continue;
			}
			// load and remember texture
			UMaterial *Tex = static_cast<UMaterial*>(Package->CreateExport(texExportIdx));
			sm->Textures.Add(Tex);
		}
		// setup UPrimitive properties using 1st animation frame
		// note: this->BoundingBox and this->BoundingSphere are null
		const RAnimFrame &F = frames[0];
		assert(strcmp(AnimSeqs[0].Name, "baseframe") == 0 && AnimSeqs[0].StartFrame == 0);
		CVec3 mins, maxs;
		sm->BoundingBox = F.bounds;
		mins = CVT(F.bounds.Min);
		maxs = CVT(F.bounds.Max);
		CVec3 &center = CVT(sm->BoundingSphere);
		for (i = 0; i < 3; i++)
			center[i] = (mins[i] + maxs[i]) / 2;
		sm->BoundingSphere.R = VectorDistance(center, mins);

		// create CSkeletalMesh
		sm->ConvertMesh();
	}

	unguard;
}
Beispiel #19
0
static void
PS_Lvl2colorspace(FILE* fd, TIFF* tif)
{
	uint16 *rmap, *gmap, *bmap;
	int i, num_colors;
	const char * colorspace_p;

	switch ( photometric )
	{
	case PHOTOMETRIC_SEPARATED:
		colorspace_p = "CMYK";
		break;

	case PHOTOMETRIC_RGB:
		colorspace_p = "RGB";
		break;

	default:
		colorspace_p = "Gray";
	}

	/*
	 * Set up PostScript Level 2 colorspace according to
	 * section 4.8 in the PostScript refenence manual.
	 */
	fputs("% PostScript Level 2 only.\n", fd);
	if (photometric != PHOTOMETRIC_PALETTE) {
		if (photometric == PHOTOMETRIC_YCBCR) {
		    /* MORE CODE HERE */
		}
		fprintf(fd, "/Device%s setcolorspace\n", colorspace_p );
		return;
	}

	/*
	 * Set up an indexed/palette colorspace
	 */
	num_colors = (1 << bitspersample);
	if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) {
		TIFFError(filename,
			"Palette image w/o \"Colormap\" tag");
		return;
	}
	if (checkcmap(tif, num_colors, rmap, gmap, bmap) == 16) {
		/*
		 * Convert colormap to 8-bits values.
		 */
#define	CVT(x)		(((x) * 255) / ((1L<<16)-1))
		for (i = 0; i < num_colors; i++) {
			rmap[i] = CVT(rmap[i]);
			gmap[i] = CVT(gmap[i]);
			bmap[i] = CVT(bmap[i]);
		}
#undef CVT
	}
	fprintf(fd, "[ /Indexed /DeviceRGB %d", num_colors - 1);
	if (ascii85) {
		Ascii85Init();
		fputs("\n<~", fd);
		ascii85breaklen -= 2;
	} else
		fputs(" <", fd);
	for (i = 0; i < num_colors; i++) {
		if (ascii85) {
			Ascii85Put(rmap[i], fd);
			Ascii85Put(gmap[i], fd);
			Ascii85Put(bmap[i], fd);
		} else {
			fputs((i % 8) ? " " : "\n  ", fd);
			fprintf(fd, "%02x%02x%02x",
			    rmap[i], gmap[i], bmap[i]);
		}
	}
	if (ascii85)
		Ascii85Flush(fd);
	else
		fputs(">\n", fd);
	fputs("] setcolorspace\n", fd);
}
Beispiel #20
0
void USkeleton::ConvertAnims(UAnimSequence4* Seq)
{
	guard(USkeleton::ConvertAnims);

	CAnimSet* AnimSet = ConvertedAnim;

	if (!AnimSet)
	{
		AnimSet = new CAnimSet(this);
		ConvertedAnim = AnimSet;

		// Copy bone names
		AnimSet->TrackBoneNames.Empty(ReferenceSkeleton.RefBoneInfo.Num());
		for (int i = 0; i < ReferenceSkeleton.RefBoneInfo.Num(); i++)
		{
			AnimSet->TrackBoneNames.Add(ReferenceSkeleton.RefBoneInfo[i].Name);
		}

		//TODO: verify if UE4 has AnimRotationOnly stuff
		AnimSet->AnimRotationOnly = false;
	}

	if (!Seq) return; // allow calling ConvertAnims(NULL) to create empty AnimSet

//	DBG("----------- Skeleton %s: %d seq, %d bones -----------\n", Name, Anims.Num(), ReferenceSkeleton.RefBoneInfo.Num());

	int NumTracks = Seq->GetNumTracks();

#if DEBUG_DECOMPRESS
	appPrintf("Sequence %s: %d bones, %d offsets (%g per bone), %d frames, %d compressed data\n"
		   "          trans %s, rot %s, scale %s, key %s\n",
		Seq->Name, NumTracks, Seq->CompressedTrackOffsets.Num(), Seq->CompressedTrackOffsets.Num() / (float)NumTracks,
		Seq->NumFrames, Seq->CompressedByteStream.Num(),
		EnumToName(Seq->TranslationCompressionFormat),
		EnumToName(Seq->RotationCompressionFormat),
		EnumToName(Seq->ScaleCompressionFormat),
		EnumToName(Seq->KeyEncodingFormat)
	);
	for (int i2 = 0; i2 < Seq->CompressedTrackOffsets.Num(); /*empty*/)
	{
		if (Seq->KeyEncodingFormat != AKF_PerTrackCompression)
		{
			FName BoneName = ReferenceSkeleton.RefBoneInfo[Seq->GetTrackBoneIndex(i2/4)].Name;
			int TransOffset = Seq->CompressedTrackOffsets[i2  ];
			int TransKeys   = Seq->CompressedTrackOffsets[i2+1];
			int RotOffset   = Seq->CompressedTrackOffsets[i2+2];
			int RotKeys     = Seq->CompressedTrackOffsets[i2+3];
			appPrintf("    [%d] = trans %d[%d] rot %d[%d] - %s\n", i2/4, TransOffset, TransKeys, RotOffset, RotKeys, *BoneName);
			i2 += 4;
		}
		else
		{
			FName BoneName = ReferenceSkeleton.RefBoneInfo[Seq->GetTrackBoneIndex(i2/2)].Name;
			int TransOffset = Seq->CompressedTrackOffsets[i2  ];
			int RotOffset   = Seq->CompressedTrackOffsets[i2+1];
			appPrintf("    [%d] = trans %d rot %d - %s\n", i2/2, TransOffset, RotOffset, *BoneName);
			i2 += 2;
		}
	}
#endif // DEBUG_DECOMPRESS

	// some checks
	int offsetsPerBone = 4;
	if (Seq->KeyEncodingFormat == AKF_PerTrackCompression)
		offsetsPerBone = 2;

	if (Seq->CompressedTrackOffsets.Num() != NumTracks * offsetsPerBone && !Seq->RawAnimationData.Num())
	{
		appNotify("AnimSequence %s has wrong CompressedTrackOffsets size (has %d, expected %d), removing track",
			Seq->Name, Seq->CompressedTrackOffsets.Num(), NumTracks * offsetsPerBone);
		return;
	}

	// create CAnimSequence
	CAnimSequence *Dst = new CAnimSequence;
	AnimSet->Sequences.Add(Dst);
	Dst->Name      = Seq->Name;
	Dst->NumFrames = Seq->NumFrames;
	Dst->Rate      = Seq->NumFrames / Seq->SequenceLength * Seq->RateScale;

	// bone tracks ...
	Dst->Tracks.Empty(NumTracks);

	FMemReader Reader(Seq->CompressedByteStream.GetData(), Seq->CompressedByteStream.Num());
	Reader.SetupFrom(*Package);

	bool HasTimeTracks = (Seq->KeyEncodingFormat == AKF_VariableKeyLerp);

	for (int BoneIndex = 0; BoneIndex < ReferenceSkeleton.RefBoneInfo.Num(); BoneIndex++)
	{
		CAnimTrack *A = new (Dst->Tracks) CAnimTrack;
		int TrackIndex = Seq->FindTrackForBoneIndex(BoneIndex);

		if (TrackIndex < 0)
		{
			// this track has no animation, use static pose from ReferenceSkeleton
			const FTransform& RefPose = ReferenceSkeleton.RefBonePose[BoneIndex];
			A->KeyPos.Add(CVT(RefPose.Translation));
			A->KeyQuat.Add(CVT(RefPose.Rotation));
			//!! RefPose.Scale3D
			continue;
		}

		int k;

		if (!Seq->CompressedTrackOffsets.Num())	//?? or if RawAnimData.Num() != 0
		{
			// using RawAnimData array
			assert(Seq->RawAnimationData.Num() == NumTracks);
			CopyArray(A->KeyPos,  CVT(Seq->RawAnimationData[TrackIndex].PosKeys));
			CopyArray(A->KeyQuat, CVT(Seq->RawAnimationData[TrackIndex].RotKeys));
			CopyArray(A->KeyTime, Seq->RawAnimationData[TrackIndex].KeyTimes);	// may be empty
			for (int k = 0; k < A->KeyTime.Num(); k++)
				A->KeyTime[k] *= Dst->Rate;
			continue;
		}

		FVector Mins, Ranges;	// common ...
		static const CVec3 nullVec  = { 0, 0, 0 };
		static const CQuat nullQuat = { 0, 0, 0, 1 };

		int offsetIndex = TrackIndex * offsetsPerBone;

		// PARAGON has invalid data inside some animation tracks. Not sure if game engine ignores them
		// or trying to process (this game has holes in data due to wrong pointers in CompressedTrackOffsets).
		// This causes garbage data to appear instead of real animation track header, with wrong compression
		// method etc. We're going to skip such tracks with displaying a warning message.
		if (0) // this is just a placeholder for error handler - it should be located somewhere
		{
		track_error:
			AnimSet->Sequences.RemoveSingle(Dst);
			delete Dst;
			return;
		}

		//----------------------------------------------
		// decode AKF_PerTrackCompression data
		//----------------------------------------------
		if (Seq->KeyEncodingFormat == AKF_PerTrackCompression)
		{
			// this format uses different key storage
			guard(PerTrackCompression);
			assert(Seq->TranslationCompressionFormat == ACF_Identity);
			assert(Seq->RotationCompressionFormat == ACF_Identity);

			int TransOffset = Seq->CompressedTrackOffsets[offsetIndex  ];
			int RotOffset   = Seq->CompressedTrackOffsets[offsetIndex+1];

			uint32 PackedInfo;
			AnimationCompressionFormat KeyFormat;
			int ComponentMask;
			int NumKeys;

#define DECODE_PER_TRACK_INFO(info)									\
			KeyFormat = (AnimationCompressionFormat)(info >> 28);	\
			ComponentMask = (info >> 24) & 0xF;						\
			NumKeys       = info & 0xFFFFFF;						\
			HasTimeTracks = (ComponentMask & 8) != 0;

			guard(TransKeys);
			// read translation keys
			if (TransOffset == -1)
			{
				A->KeyPos.Add(nullVec);
				DBG("    [%d] no translation data\n", TrackIndex);
			}
			else
			{
				Reader.Seek(TransOffset);
				Reader << PackedInfo;
				DECODE_PER_TRACK_INFO(PackedInfo);
				A->KeyPos.Empty(NumKeys);
				DBG("    [%d] trans: fmt=%d (%s), %d keys, mask %d\n", TrackIndex,
					KeyFormat, EnumToName(KeyFormat), NumKeys, ComponentMask
				);
				if (KeyFormat == ACF_IntervalFixed32NoW)
				{
					// read mins/maxs
					Mins.Set(0, 0, 0);
					Ranges.Set(0, 0, 0);
					if (ComponentMask & 1) Reader << Mins.X << Ranges.X;
					if (ComponentMask & 2) Reader << Mins.Y << Ranges.Y;
					if (ComponentMask & 4) Reader << Mins.Z << Ranges.Z;
				}
				for (k = 0; k < NumKeys; k++)
				{
					switch (KeyFormat)
					{
//					case ACF_None:
					case ACF_Float96NoW:
						{
							FVector v;
							if (ComponentMask & 7)
							{
								v.Set(0, 0, 0);
								if (ComponentMask & 1) Reader << v.X;
								if (ComponentMask & 2) Reader << v.Y;
								if (ComponentMask & 4) Reader << v.Z;
							}
							else
							{
								// ACF_Float96NoW has a special case for ((ComponentMask & 7) == 0)
								Reader << v;
							}
							A->KeyPos.Add(CVT(v));
						}
						break;
					TPR(ACF_IntervalFixed32NoW, FVectorIntervalFixed32)
					case ACF_Fixed48NoW:
						{
							uint16 X, Y, Z;
							CVec3 v;
							v.Set(0, 0, 0);
							if (ComponentMask & 1)
							{
								Reader << X; v[0] = DecodeFixed48_PerTrackComponent<7>(X);
							}
							if (ComponentMask & 2)
							{
								Reader << Y; v[1] = DecodeFixed48_PerTrackComponent<7>(Y);
							}
							if (ComponentMask & 4)
							{
								Reader << Z; v[2] = DecodeFixed48_PerTrackComponent<7>(Z);
							}
							A->KeyPos.Add(v);
						}
						break;
					case ACF_Identity:
						A->KeyPos.Add(nullVec);
						break;
					default:
						{
							char buf[1024];
							Seq->GetFullName(buf, 1024);
							appNotify("%s: unknown translation compression method: %d (%s) - dropping track", buf, KeyFormat, EnumToName(KeyFormat));
							goto track_error;
						}
					}
				}
				// align to 4 bytes
				Reader.Seek(Align(Reader.Tell(), 4));
				if (HasTimeTracks)
					ReadTimeArray(Reader, NumKeys, A->KeyPosTime, Seq->NumFrames);
			}
			unguard;

			guard(RotKeys);
			// read rotation keys
			if (RotOffset == -1)
			{
				A->KeyQuat.Add(nullQuat);
				DBG("    [%d] no rotation data\n", TrackIndex);
			}
			else
			{
				Reader.Seek(RotOffset);
				Reader << PackedInfo;
				DECODE_PER_TRACK_INFO(PackedInfo);
				A->KeyQuat.Empty(NumKeys);
				DBG("    [%d] rot  : fmt=%d (%s), %d keys, mask %d\n", TrackIndex,
					KeyFormat, EnumToName(KeyFormat), NumKeys, ComponentMask
				);
				if (KeyFormat == ACF_IntervalFixed32NoW)
				{
					// read mins/maxs
					Mins.Set(0, 0, 0);
					Ranges.Set(0, 0, 0);
					if (ComponentMask & 1) Reader << Mins.X << Ranges.X;
					if (ComponentMask & 2) Reader << Mins.Y << Ranges.Y;
					if (ComponentMask & 4) Reader << Mins.Z << Ranges.Z;
				}
				for (k = 0; k < NumKeys; k++)
				{
					switch (KeyFormat)
					{
//					TR (ACF_None, FQuat)
					case ACF_Float96NoW:
						{
							FQuatFloat96NoW q;
							Reader << q;
							FQuat q2 = q;				// convert
							A->KeyQuat.Add(CVT(q2));
						}
						break;
					case ACF_Fixed48NoW:
						{
							FQuatFixed48NoW q;
							q.X = q.Y = q.Z = 32767;	// corresponds to 0
							if (ComponentMask & 1) Reader << q.X;
							if (ComponentMask & 2) Reader << q.Y;
							if (ComponentMask & 4) Reader << q.Z;
							FQuat q2 = q;				// convert
							A->KeyQuat.Add(CVT(q2));
						}
						break;
					TR (ACF_Fixed32NoW, FQuatFixed32NoW)
					TRR(ACF_IntervalFixed32NoW, FQuatIntervalFixed32NoW)
					TR (ACF_Float32NoW, FQuatFloat32NoW)
					case ACF_Identity:
						A->KeyQuat.Add(nullQuat);
						break;
					default:
						{
							char buf[1024];
							Seq->GetFullName(buf, 1024);
							appNotify("%s: unknown rotation compression method: %d (%s) - dropping track", buf, KeyFormat, EnumToName(KeyFormat));
							goto track_error;
						}
					}
				}
				// align to 4 bytes
				Reader.Seek(Align(Reader.Tell(), 4));
				if (HasTimeTracks)
					ReadTimeArray(Reader, NumKeys, A->KeyQuatTime, Seq->NumFrames);
			}
			unguard;

			unguard;
			continue;
			// end of AKF_PerTrackCompression block ...
		}

		//----------------------------------------------
		// end of AKF_PerTrackCompression decoder
		//----------------------------------------------

		// read animations
		int TransOffset = Seq->CompressedTrackOffsets[offsetIndex  ];
		int TransKeys   = Seq->CompressedTrackOffsets[offsetIndex+1];
		int RotOffset   = Seq->CompressedTrackOffsets[offsetIndex+2];
		int RotKeys     = Seq->CompressedTrackOffsets[offsetIndex+3];
//		appPrintf("[%d:%d:%d] :  %d[%d]  %d[%d]  %d[%d]\n", j, Seq->RotationCompressionFormat, Seq->TranslationCompressionFormat, TransOffset, TransKeys, RotOffset, RotKeys, ScaleOffset, ScaleKeys);

		A->KeyPos.Empty(TransKeys);
		A->KeyQuat.Empty(RotKeys);

		// read translation keys
		if (TransKeys)
		{
			Reader.Seek(TransOffset);
			AnimationCompressionFormat TranslationCompressionFormat = Seq->TranslationCompressionFormat;
			if (TransKeys == 1)
				TranslationCompressionFormat = ACF_None;	// single key is stored without compression
			// read mins/ranges
			if (TranslationCompressionFormat == ACF_IntervalFixed32NoW)
			{
				Reader << Mins << Ranges;
			}

			for (k = 0; k < TransKeys; k++)
			{
				switch (TranslationCompressionFormat)
				{
				TP (ACF_None,               FVector)
				TP (ACF_Float96NoW,         FVector)
				TPR(ACF_IntervalFixed32NoW, FVectorIntervalFixed32)
				TP (ACF_Fixed48NoW,         FVectorFixed48)
				case ACF_Identity:
					A->KeyPos.Add(nullVec);
					break;
				default:
					appError("Unknown translation compression method: %d (%s)", TranslationCompressionFormat, EnumToName(TranslationCompressionFormat));
				}
			}

			// align to 4 bytes
			Reader.Seek(Align(Reader.Tell(), 4));
			if (HasTimeTracks)
				ReadTimeArray(Reader, TransKeys, A->KeyPosTime, Seq->NumFrames);
		}
		else
		{
//			A->KeyPos.Add(nullVec);
//			appNotify("No translation keys!");
		}
Beispiel #21
0
int
main(int argc, char* argv[])
{
	uint32 rowsperstrip = (uint32) -1;
	TIFF *in, *out;
	uint32 w, h;
	uint16 samplesperpixel;
	uint16 bitspersample;
	uint16 config;
	uint16 photometric;
	uint16* red;
	uint16* green;
	uint16* blue;
	tsize_t rowsize;
	register uint32 row;
	register tsample_t s;
	unsigned char *inbuf, *outbuf;
	char thing[1024];
	int c;
	extern int optind;
	extern char *optarg;

	while ((c = getopt(argc, argv, "c:r:R:G:B:")) != -1)
		switch (c) {
		case 'c':		/* compression scheme */
			if (!processCompressOptions(optarg))
				usage();
			break;
		case 'r':		/* rows/strip */
			rowsperstrip = atoi(optarg);
			break;
		case 'R':
			RED = PCT(atoi(optarg));
			break;
		case 'G':
			GREEN = PCT(atoi(optarg));
			break;
		case 'B':
			BLUE = PCT(atoi(optarg));
			break;
		case '?':
			usage();
			/*NOTREACHED*/
		}
	if (argc - optind < 2)
		usage();
	in = TIFFOpen(argv[optind], "r");
	if (in == NULL)
		return (-1);
	photometric = 0;
	TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &photometric);
	if (photometric != PHOTOMETRIC_RGB && photometric != PHOTOMETRIC_PALETTE ) {
		fprintf(stderr,
	    "%s: Bad photometric; can only handle RGB and Palette images.\n",
		    argv[optind]);
		return (-1);
	}
	TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
	if (samplesperpixel != 1 && samplesperpixel != 3) {
		fprintf(stderr, "%s: Bad samples/pixel %u.\n",
		    argv[optind], samplesperpixel);
		return (-1);
	}
	TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample);
	if (bitspersample != 8) {
		fprintf(stderr,
		    " %s: Sorry, only handle 8-bit samples.\n", argv[optind]);
		return (-1);
	}
	TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &w);
	TIFFGetField(in, TIFFTAG_IMAGELENGTH, &h);
	TIFFGetField(in, TIFFTAG_PLANARCONFIG, &config);

	out = TIFFOpen(argv[optind+1], "w");
	if (out == NULL)
		return (-1);
	cpTags(in, out);
	TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8);
	TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 1);
	TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
	if (compression != (uint16) -1) {
		TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
		switch (compression) {
		case COMPRESSION_JPEG:
			TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
			TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
			break;
		case COMPRESSION_LZW:
		case COMPRESSION_DEFLATE:
			if (predictor != 0)
				TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
			break;
		}
	}
	TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
	sprintf(thing, "B&W version of %s", argv[optind]);
	TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, thing);
	TIFFSetField(out, TIFFTAG_SOFTWARE, "tiff2bw");
	outbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(out));
	TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
	    TIFFDefaultStripSize(out, rowsperstrip));

#define	pack(a,b)	((a)<<8 | (b))
	switch (pack(photometric, config)) {
	case pack(PHOTOMETRIC_PALETTE, PLANARCONFIG_CONTIG):
	case pack(PHOTOMETRIC_PALETTE, PLANARCONFIG_SEPARATE):
		TIFFGetField(in, TIFFTAG_COLORMAP, &red, &green, &blue);
		/*
		 * Convert 16-bit colormap to 8-bit (unless it looks
		 * like an old-style 8-bit colormap).
		 */
		if (checkcmap(in, 1<<bitspersample, red, green, blue) == 16) {
			int i;
#define	CVT(x)		(((x) * 255L) / ((1L<<16)-1))
			for (i = (1<<bitspersample)-1; i >= 0; i--) {
				red[i] = CVT(red[i]);
				green[i] = CVT(green[i]);
				blue[i] = CVT(blue[i]);
			}
#undef CVT
		}
		inbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in));
		for (row = 0; row < h; row++) {
			if (TIFFReadScanline(in, inbuf, row, 0) < 0)
				break;
			compresspalette(outbuf, inbuf, w, red, green, blue);
			if (TIFFWriteScanline(out, outbuf, row, 0) < 0)
				break;
		}
		break;
	case pack(PHOTOMETRIC_RGB, PLANARCONFIG_CONTIG):
		inbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in));
		for (row = 0; row < h; row++) {
			if (TIFFReadScanline(in, inbuf, row, 0) < 0)
				break;
			compresscontig(outbuf, inbuf, w);
			if (TIFFWriteScanline(out, outbuf, row, 0) < 0)
				break;
		}
		break;
	case pack(PHOTOMETRIC_RGB, PLANARCONFIG_SEPARATE):
		rowsize = TIFFScanlineSize(in);
		inbuf = (unsigned char *)_TIFFmalloc(3*rowsize);
		for (row = 0; row < h; row++) {
			for (s = 0; s < 3; s++)
				if (TIFFReadScanline(in,
				    inbuf+s*rowsize, row, s) < 0)
					 return (-1);
			compresssep(outbuf,
			    inbuf, inbuf+rowsize, inbuf+2*rowsize, w);
			if (TIFFWriteScanline(out, outbuf, row, 0) < 0)
				break;
		}
		break;
	}
#undef pack
	TIFFClose(out);
	return (0);
}
Beispiel #22
0
unsigned char *
simage_tiff_load(std::istream& fin,
                 int& width_ret,
                 int& height_ret,
                 int& numComponents_ret,
                 uint16& bitspersample)
{
    TIFF *in;
    uint16 dataType;
    uint16 samplesperpixel;
    uint16 photometric;
    uint32 w, h;
    uint16 config;
    uint16* red;
    uint16* green;
    uint16* blue;
    unsigned char *inbuf = NULL;
    tsize_t rowsize;
    uint32 row;
    int format;
    unsigned char *buffer;
    int width;
    int height;
    unsigned char *currPtr;

    TIFFSetErrorHandler(tiff_error);
    TIFFSetWarningHandler(tiff_warn);

    in = TIFFClientOpen("inputstream", "r", (thandle_t)&fin,
            libtiffStreamReadProc, //Custom read function
            libtiffStreamWriteProc, //Custom write function
            libtiffStreamSeekProc, //Custom seek function
            libtiffStreamCloseProc, //Custom close function
            libtiffStreamSizeProc, //Custom size function
            libtiffStreamMapProc, //Custom map function
            libtiffStreamUnmapProc); //Custom unmap function

    if (in == NULL)
    {
        tifferror = ERR_OPEN;
        return NULL;
    }
    if (TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &photometric) == 1)
    {
        if (photometric != PHOTOMETRIC_RGB && photometric != PHOTOMETRIC_PALETTE &&
            photometric != PHOTOMETRIC_MINISWHITE &&
            photometric != PHOTOMETRIC_MINISBLACK)
        {
            OSG_NOTICE << "Photometric type "<<photometric<<" not handled; can only handle Grayscale, RGB and Palette images" << std::endl;
            TIFFClose(in);
            tifferror = ERR_UNSUPPORTED;
            return NULL;
        }
    }
    else
    {
        tifferror = ERR_READ;
        TIFFClose(in);
        return NULL;
    }

    if (TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel) == 1)
    {
        if (samplesperpixel != 1 &&
            samplesperpixel != 2 &&
            samplesperpixel != 3 &&
            samplesperpixel != 4)
        {
            OSG_DEBUG << "Bad samples/pixel" << std::endl;
            tifferror = ERR_UNSUPPORTED;
            TIFFClose(in);
            return NULL;
        }
    }
    else
    {
        tifferror = ERR_READ;
        TIFFClose(in);
        return NULL;
    }

    if (TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample) == 1)
    {
         if (bitspersample != 8 && bitspersample != 16 && bitspersample != 32)
        {
            OSG_NOTICE << "can only handle 8, 16 and 32 bit samples" << std::endl;
            TIFFClose(in);
            tifferror = ERR_UNSUPPORTED;
            return NULL;
        }
    }
    else
    {
        tifferror = ERR_READ;
        TIFFClose(in);
        return NULL;
    }

    if (TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &w) != 1 ||
        TIFFGetField(in, TIFFTAG_IMAGELENGTH, &h) != 1 ||
        TIFFGetField(in, TIFFTAG_PLANARCONFIG, &config) != 1)
    {
        TIFFClose(in);
        tifferror = ERR_READ;
        return NULL;
    }


    TIFFGetField(in, TIFFTAG_DATATYPE, &dataType);
    OSG_INFO<<"TIFFTAG_DATATYPE="<<dataType<<std::endl;


    /*
    if (photometric == PHOTOMETRIC_MINISWHITE ||
        photometric == PHOTOMETRIC_MINISBLACK)
        format = 1;
    else
        format = 3;
    */
    // if it has a palette, data returned is 3 byte rgb
    // so set format to 3.
    if (photometric == PHOTOMETRIC_PALETTE)
        format = 3;
    else
        format = samplesperpixel * bitspersample / 8;


    int bytespersample = bitspersample / 8;
    int bytesperpixel = bytespersample * samplesperpixel;

    OSG_INFO<<"format="<<format<<std::endl;
    OSG_INFO<<"bytespersample="<<bytespersample<<std::endl;
    OSG_INFO<<"bytesperpixel="<<bytesperpixel<<std::endl;

    buffer = new unsigned char [w*h*format];

    if (!buffer)
    {
        tifferror = ERR_MEM;
        TIFFClose(in);
        return NULL;
    }

    // initialize memory
    for(unsigned char* ptr=buffer;ptr<buffer+w*h*format;++ptr) *ptr = 0;

    width = w;
    height = h;

    currPtr = buffer + (h-1)*w*format;

    tifferror = ERR_NO_ERROR;

    switch (pack(photometric, config))
    {
        case pack(PHOTOMETRIC_MINISWHITE, PLANARCONFIG_CONTIG):
        case pack(PHOTOMETRIC_MINISBLACK, PLANARCONFIG_CONTIG):
        case pack(PHOTOMETRIC_MINISWHITE, PLANARCONFIG_SEPARATE):
        case pack(PHOTOMETRIC_MINISBLACK, PLANARCONFIG_SEPARATE):
            inbuf = new unsigned char [TIFFScanlineSize(in)];
            for (row = 0; row < h; row++)
            {
                if (TIFFReadScanline(in, inbuf, row, 0) < 0)
                {
                    tifferror = ERR_READ;
                    break;
                }
                invert_row(currPtr, inbuf, samplesperpixel*w, photometric == PHOTOMETRIC_MINISWHITE, bitspersample);
                currPtr -= format*w;
            }
            break;

        case pack(PHOTOMETRIC_PALETTE, PLANARCONFIG_CONTIG):
        case pack(PHOTOMETRIC_PALETTE, PLANARCONFIG_SEPARATE):
            if (TIFFGetField(in, TIFFTAG_COLORMAP, &red, &green, &blue) != 1)
                tifferror = ERR_READ;
            /* */
            /* Convert 16-bit colormap to 8-bit (unless it looks */
            /* like an old-style 8-bit colormap). */
            /* */
            if (!tifferror && checkcmap(1<<bitspersample, red, green, blue) == 16)
            {
                int i;
                for (i = (1<<bitspersample)-1; i >= 0; i--)
                {
                    red[i] = CVT(red[i]);
                    green[i] = CVT(green[i]);
                    blue[i] = CVT(blue[i]);
                }
            }

            inbuf = new unsigned char [TIFFScanlineSize(in)];
            for (row = 0; row < h; row++)
            {
                if (TIFFReadScanline(in, inbuf, row, 0) < 0)
                {
                    tifferror = ERR_READ;
                    break;
                }
                remap_row(currPtr, inbuf, w, red, green, blue);
                currPtr -= format*w;
            }
            break;

        case pack(PHOTOMETRIC_RGB, PLANARCONFIG_CONTIG):
            inbuf = new unsigned char [TIFFScanlineSize(in)];
            for (row = 0; row < h; row++)
            {
                if (TIFFReadScanline(in, inbuf, row, 0) < 0)
                {
                    tifferror = ERR_READ;
                    break;
                }
                memcpy(currPtr, inbuf, format*w);
                currPtr -= format*w;
            }
            break;

        case pack(PHOTOMETRIC_RGB, PLANARCONFIG_SEPARATE):
            rowsize = TIFFScanlineSize(in);
            inbuf = new unsigned char [format*rowsize];
            for (row = 0; !tifferror && row < h; row++)
            {
                int s;
                for (s = 0; s < format; s++)
                {
                    if (TIFFReadScanline(in, (tdata_t)(inbuf+s*rowsize), (uint32)row, (tsample_t)s) < 0)
                    {
                        tifferror = ERR_READ; break;
                    }
                }
                if (!tifferror)
                {
                    if (format==3) interleave_row(currPtr, inbuf, inbuf+rowsize, inbuf+2*rowsize, w, format, bitspersample);
                    else if (format==4) interleave_row(currPtr, inbuf, inbuf+rowsize, inbuf+2*rowsize, inbuf+3*rowsize, w, format, bitspersample);
                    currPtr -= format*w;
                }
            }
            break;
        default:
            tifferror = ERR_UNSUPPORTED;
            break;
    }

    if (inbuf) delete [] inbuf;
    TIFFClose(in);

    if (tifferror)
    {
        if (buffer) delete [] buffer;
        return NULL;
    }
    width_ret = width;
    height_ret = height;
    if (photometric == PHOTOMETRIC_PALETTE)
        numComponents_ret = format;
    else
        numComponents_ret = samplesperpixel;

    return buffer;
}
Beispiel #23
0
boolean TIFFRasterImpl::gt(u_long w, u_long h) {
    u_short minsamplevalue;
    u_short maxsamplevalue;
    u_short planarconfig;
    RGBvalue* Map = nil;

    if (!TIFFGetField(tif_, TIFFTAG_MINSAMPLEVALUE, &minsamplevalue)) {
	minsamplevalue = 0;
    }
    if (!TIFFGetField(tif_, TIFFTAG_MAXSAMPLEVALUE, &maxsamplevalue)) {
	maxsamplevalue = (1<<bitspersample_)-1;
    }
    switch (photometric_) {
    case PHOTOMETRIC_RGB:
	if (minsamplevalue == 0 && maxsamplevalue == 255) {
	    break;
	}
	/* fall thru... */
    case PHOTOMETRIC_MINISBLACK:
    case PHOTOMETRIC_MINISWHITE: {
	register int x, range;

	range = maxsamplevalue - minsamplevalue;
	Map = new RGBvalue[range + 1];
	if (Map == nil) {
	    TIFFError(
		TIFFFileName(tif_),
		"No space for photometric conversion table"
	    );
	    return false;
	}
	if (photometric_ == PHOTOMETRIC_MINISWHITE) {
	    for (x = 0; x <= range; x++) {
		Map[x] = ((range - x) * 255) / range;
	    }
	} else {
	    for (x = 0; x <= range; x++) {
		Map[x] = (x * 255) / range;
	    }
	}
	if (photometric_ != PHOTOMETRIC_RGB && bitspersample_ != 8) {
	    /*
	     * Use photometric mapping table to construct
	     * unpacking tables for samples < 8 bits.
	     */
	    if (!makebwmap(Map)) {
		return false;
	    }
	    delete Map;			/* no longer need Map, free it */
	    Map = nil;
	}
	break;
    }
    case PHOTOMETRIC_PALETTE:
	if (!TIFFGetField(
	    tif_, TIFFTAG_COLORMAP, &redcmap_, &greencmap_, &bluecmap_)
	) {
	    TIFFError(TIFFFileName(tif_), "Missing required \"Colormap\" tag");
	    return (false);
	}
	/*
	 * Convert 16-bit colormap to 8-bit (unless it looks
	 * like an old-style 8-bit colormap).
	 */
	if (
	    checkcmap(
		1 << bitspersample_, redcmap_, greencmap_, bluecmap_
	    ) == 16
	) {
	    int i;
	    for (i = (1 << bitspersample_) - 1; i > 0; i--) {
#define	CVT(x)		(((x) * 255) / ((1L<<16)-1))
		redcmap_[i] = (u_short) CVT(redcmap_[i]);
		greencmap_[i] = (u_short) CVT(greencmap_[i]);
		bluecmap_[i] = (u_short) CVT(bluecmap_[i]);
	    }
	}
	if (bitspersample_ <= 8) {
	    /*
	     * Use mapping table and colormap to construct
	     * unpacking tables for samples < 8 bits.
	     */
	    if (!makecmap(redcmap_, greencmap_, bluecmap_)) {
		return false;
	    }
	}
	break;
    }
    TIFFGetField(tif_, TIFFTAG_PLANARCONFIG, &planarconfig);
    boolean e;
    if (planarconfig == PLANARCONFIG_SEPARATE && samplesperpixel_ > 1) {
	e = TIFFIsTiled(tif_) ?
	    gtTileSeparate(Map, h, w) : gtStripSeparate(Map, h, w);
    } else {
	e = TIFFIsTiled(tif_) ? 
	    gtTileContig(Map, h, w) : gtStripContig(Map, h, w);
    }
    delete Map;
    return e;
}
Beispiel #24
0
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;
}
Beispiel #25
0
HDIB LoadTIFFinDIB(LPSTR lpFileName)
{
    TIFF          *tif;
    unsigned long imageLength;
    unsigned long imageWidth;
    unsigned int  BitsPerSample;
    unsigned long LineSize;
    unsigned int  SamplePerPixel;
    unsigned long RowsPerStrip;
    int           PhotometricInterpretation;
    long          nrow;
    unsigned long row;
    char          *buf;
    LPBITMAPINFOHEADER lpDIB;
    HDIB          hDIB;
    char          *lpBits;
    HGLOBAL       hStrip;
    int           i,l;
    int           Align;

    tif = TIFFOpen(lpFileName, "r");

    if (!tif)
        goto TiffOpenError;

    TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imageWidth);
    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imageLength);
    TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &BitsPerSample);
    TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip);
    TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip);
    TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &PhotometricInterpretation);

    LineSize = TIFFScanlineSize(tif); //Number of byte in ine line

    SamplePerPixel = (int) (LineSize/imageWidth);

    //Align = Number of byte to add at the end of each line of the DIB
    Align = 4 - (LineSize % 4);
    if (Align == 4)	Align = 0;


    //Create a new DIB
    hDIB = CreateDIB((DWORD) imageWidth, (DWORD) imageLength, (WORD)
                     (BitsPerSample*SamplePerPixel));
    lpDIB  = (LPBITMAPINFOHEADER) GlobalLock(hDIB);
    if (!lpDIB)
        goto OutOfDIBMemory;

    if (lpDIB)
        lpBits = FindDIBBits((LPSTR) lpDIB);

    //In the tiff file the lines are save from up to down
    //In a DIB the lines must be save from down to up
    if (lpBits)
    {
        lpBits = FindDIBBits((LPSTR) lpDIB);
        lpBits+=((imageWidth*SamplePerPixel)+Align)*(imageLength-1);
        //now lpBits pointe on the bottom line

        hStrip = GlobalAlloc(GHND,TIFFStripSize(tif));
        buf = GlobalLock(hStrip);

        if (!buf)
            goto OutOfBufMemory;

        //PhotometricInterpretation = 2 image is RGB
        //PhotometricInterpretation = 3 image have a color palette
        if (PhotometricInterpretation == 3)
        {
            uint16* red;
            uint16* green;
            uint16* blue;
            int16 i;
            LPBITMAPINFO lpbmi;
            int   Palette16Bits;

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

            //Is the palette 16 or 8 bits ?
            if (checkcmap(1<<BitsPerSample, red, green, blue) == 16)
                Palette16Bits = TRUE;
            else
                Palette16Bits = FALSE;

            lpbmi = (LPBITMAPINFO)lpDIB;

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

        }

        //read the tiff lines and save them in the DIB
        //with RGB mode, we have to change the order of the 3 samples RGB
        <=> BGR
        for (row = 0; row < imageLength; row += RowsPerStrip)
        {
            nrow = (row + RowsPerStrip > imageLength ? imageLength - row :
                    RowsPerStrip);
            if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
                                     buf, nrow*LineSize)==-1)
            {
                goto TiffReadError;
            }
            else
            {
                for (l = 0; l < nrow; l++)
                {
                    if (SamplePerPixel  == 3)
                        for (i=0; i< (int) (imageWidth); i++)
                        {
                            lpBits[i*SamplePerPixel+0]=buf[l*LineSize+i*Sample
                                                           PerPixel+2];
                            lpBits[i*SamplePerPixel+1]=buf[l*LineSize+i*Sample
                                                           PerPixel+1];
                            lpBits[i*SamplePerPixel+2]=buf[l*LineSize+i*Sample
                                                           PerPixel+0];
                        }
                    else
                        memcpy(lpBits, &buf[(int) (l*LineSize)], (int)
                               imageWidth*SamplePerPixel);

                    lpBits-=imageWidth*SamplePerPixel+Align;

                }
            }
        }
        GlobalUnlock(hStrip);
        GlobalFree(hStrip);
        GlobalUnlock(hDIB);
        TIFFClose(tif);
    }
Beispiel #26
0
void USkeletalMesh::ConvertWedges(CSkelMeshLod &Lod, const TArray<FVector> &MeshPoints, const TArray<FMeshWedge> &MeshWedges, const TArray<FVertInfluence> &VertInfluences)
{
	guard(USkeletalMesh::ConvertWedges);

	struct CVertInfo
	{
		int		NumInfs;		// may be higher than NUM_INFLUENCES
		int		Bone[NUM_INFLUENCES];
		float	Weight[NUM_INFLUENCES];
	};

	int i, j;

	CVertInfo *Verts = new CVertInfo[MeshPoints.Num()];
	memset(Verts, 0, MeshPoints.Num() * sizeof(CVertInfo));

	// collect influences per vertex
	for (i = 0; i < VertInfluences.Num(); i++)
	{
		const FVertInfluence &Inf = VertInfluences[i];
		CVertInfo &V = Verts[Inf.PointIndex];
		int NumInfs = V.NumInfs++;
		int idx = NumInfs;
		if (NumInfs >= NUM_INFLUENCES)
		{
			// overflow
			// find smallest weight smaller than current
			float w = Inf.Weight;
			idx = -1;
			for (j = 0; j < NUM_INFLUENCES; j++)
			{
				if (V.Weight[j] < w)
				{
					w = V.Weight[j];
					idx = j;
					// continue - may be other weight will be even smaller
				}
			}
			if (idx < 0) continue;	// this weight is smaller than other
		}
		// add influence
		V.Bone[idx]   = Inf.BoneIndex;
		V.Weight[idx] = Inf.Weight;
	}

	// normalize influences
	for (i = 0; i < MeshPoints.Num(); i++)
	{
		CVertInfo &V = Verts[i];
		if (V.NumInfs == 0)
		{
			appPrintf("WARNING: Vertex %d has 0 influences\n", i);
			V.NumInfs = 1;
			V.Bone[0] = 0;
			V.Weight[0] = 1.0f;
			continue;
		}
		if (V.NumInfs <= NUM_INFLUENCES) continue;	// no normalization is required
		float s = 0;
		for (j = 0; j < NUM_INFLUENCES; j++)		// count sum
			s += V.Weight[j];
		s = 1.0f / s;
		for (j = 0; j < NUM_INFLUENCES; j++)		// adjust weights
			V.Weight[j] *= s;
	}

	// create vertices
	Lod.AllocateVerts(MeshWedges.Num());
	for (i = 0; i < MeshWedges.Num(); i++)
	{
		const FMeshWedge &SW = MeshWedges[i];
		CSkelMeshVertex  &DW = Lod.Verts[i];
		DW.Position = CVT(MeshPoints[SW.iVertex]);
		DW.UV = CVT(SW.TexUV);
		// DW.Normal and DW.Tangent are unset
		// setup Bone[] and Weight[]
		const CVertInfo &V = Verts[SW.iVertex];
		unsigned PackedWeights = 0;
		for (j = 0; j < V.NumInfs; j++)
		{
			DW.Bone[j]   = V.Bone[j];
			PackedWeights |= appRound(V.Weight[j] * 255) << (j * 8);
		}
		DW.PackedWeights = PackedWeights;
		for (/* continue */; j < NUM_INFLUENCES; j++)	// place end marker and zero weight
		{
			DW.Bone[j] = -1;
		}
	}

	delete Verts;

	unguard;
}
Beispiel #27
0
void CVertMeshInstance::Draw(unsigned flags)
{
	guard(CVertMeshInstance::Draw);

	if (!Sections.Num()) return;		// empty mesh

	int i;

	// get 2 frames for interpolation
	int FrameNum1, FrameNum2;
	float frac;
	if (AnimIndex != INDEX_NONE)
	{
		const FMeshAnimSeq &A = pMesh->AnimSeqs[AnimIndex];
		FrameNum1 = appFloor(AnimTime);
		FrameNum2 = FrameNum1 + 1;
		if (FrameNum2 >= A.NumFrames)
			FrameNum2 = 0;
		frac      = AnimTime - FrameNum1;
		FrameNum1 += A.StartFrame;
		FrameNum2 += A.StartFrame;
		// clamp frame numbers (has mesh with wrong frame count in last animation:
		// UT1/BotPack/cdgunmainM; this animation is shown in UnrealEd as lerping to null size)
		if (FrameNum1 >= pMesh->FrameCount)
			FrameNum1 = pMesh->FrameCount-1;
		if (FrameNum2 >= pMesh->FrameCount)
			FrameNum2 = pMesh->FrameCount-1;
	}
	else
	{
		FrameNum1 = 0;
		FrameNum2 = 0;
		frac      = 0;
	}

	int base1 = pMesh->VertexCount * FrameNum1;
	int base2 = pMesh->VertexCount * FrameNum2;

	float backLerp = 1 - frac;
	CVec3 Scale1, Scale2;
	Scale1 = Scale2 = CVT(pMesh->MeshScale);
	Scale1.Scale(backLerp);
	Scale2.Scale(frac);

	// compute deformed mesh
	const FMeshWedge *W = &pMesh->Wedges[0];
	CVec3 *pVec    = Verts;
	CVec3 *pNormal = Normals;
	for (i = 0; i < pMesh->Wedges.Num(); i++, pVec++, pNormal++, W++)
	{
		CVec3 tmp;
#if 0
		// path with no frame lerp
		// vertex
		const FMeshVert &V = pMesh->Verts[base1 + W->iVertex];
		tmp[0] = V.X * pMesh->MeshScale.X;
		tmp[1] = V.Y * pMesh->MeshScale.Y;
		tmp[2] = V.Z * pMesh->MeshScale.Z;
		BaseTransform.TransformPoint(tmp, *pVec);
		// normal
		const FMeshNorm &N = pMesh->Normals[base1 + W->iVertex];
		tmp[0] = (N.X - 512.0f) / 512;
		tmp[1] = (N.Y - 512.0f) / 512;
		tmp[2] = (N.Z - 512.0f) / 512;
		BaseTransform.axis.TransformVector(tmp, *pNormal);
#else
		// vertex
		const FMeshVert &V1 = pMesh->Verts[base1 + W->iVertex];
		const FMeshVert &V2 = pMesh->Verts[base2 + W->iVertex];
		tmp[0] = V1.X * Scale1[0] + V2.X * Scale2[0];
		tmp[1] = V1.Y * Scale1[1] + V2.Y * Scale2[1];
		tmp[2] = V1.Z * Scale1[2] + V2.Z * Scale2[2];
		BaseTransform.TransformPoint(tmp, *pVec);
		// normal
		const FMeshNorm &N1 = pMesh->Normals[base1 + W->iVertex];
		const FMeshNorm &N2 = pMesh->Normals[base2 + W->iVertex];
		tmp[0] = (N1.X * backLerp + N2.X * frac - 512.0f) / 512;
		tmp[1] = (N1.Y * backLerp + N2.Y * frac - 512.0f) / 512;
		tmp[2] = (N1.Z * backLerp + N2.Z * frac - 512.0f) / 512;
		BaseTransform.axis.TransformVector(tmp, *pNormal);
#endif
	}

#if 0
	glBegin(GL_POINTS);
	for (i = 0; i < pMesh->Wedges.Num(); i++)
	{
		glVertex3fv(Verts[i].v);
	}
	glEnd();
	return;
#endif

	// draw mesh
	glEnable(GL_LIGHTING);

	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	glEnableClientState(GL_NORMAL_ARRAY);

	glVertexPointer(3, GL_FLOAT, sizeof(CVec3), Verts);
	glNormalPointer(GL_FLOAT, sizeof(CVec3), Normals);
	glTexCoordPointer(2, GL_FLOAT, sizeof(FMeshWedge), &pMesh->Wedges[0].TexUV.U);

	for (i = 0; i < Sections.Num(); i++)
	{
		const CMeshSection &Sec = Sections[i];
		if (!Sec.NumFaces) continue;
		SetMaterial(Sec.Material, i);
		glDrawElements(GL_TRIANGLES, Sec.NumFaces * 3, GL_UNSIGNED_SHORT, &Indices[Sec.FirstIndex]);
	}

	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	glDisableClientState(GL_NORMAL_ARRAY);

	glDisable(GL_LIGHTING);
	BindDefaultMaterial(true);

	// draw mesh normals
	if (flags & DF_SHOW_NORMALS)
	{
		glBegin(GL_LINES);
		glColor3f(0.5, 1, 0);
		for (i = 0; i < pMesh->Wedges.Num(); i++)
		{
			glVertex3fv(Verts[i].v);
			CVec3 tmp;
			VectorMA(Verts[i], 2, Normals[i], tmp);
			glVertex3fv(tmp.v);
		}
		glEnd();
	}

	unguard;
}