Exemplo n.º 1
0
static Errcode read_strip_offsets(Tiff_file *tf, long offset, int type, int strip_count)
/*****************************************************************************
 * allocate the strip_data array and load strip offsets into it.
 *	note that we allocate one extra Strip_data slot in the array, in case we
 *	have to calculate strip bytecounts from the offsets later.
 ****************************************************************************/
{
	int 		counter;
	Strip_data	*curstrip;
	Onum		readbuf;

	tf->strips_per_image = strip_count;

	if (NULL != tf->strip_data) 	/* somehow got strip offset data twice */
		return Err_format;

	if (NULL == (tf->strip_data = malloc((strip_count+1) * sizeof(Strip_data))))
		return Err_no_memory;

	curstrip = tf->strip_data;

	if (strip_count == 1 && type == TYPE_LONG)		/* 1 longword is easy */
		{
		curstrip->offset = offset;
		}
	else if (strip_count == 2 && type == TYPE_SHORT)/* 2 shorts is tricky */
		{
		convert.dword = offset;
		curstrip->offset = convert.words.word1;
		++curstrip;
		curstrip->offset = convert.words.word2;
		}
	else											/* else we have to read */
		{
		if (Success != fseek(tf->file, offset, SEEK_SET))
			return pj_errno_errcode();

		counter = strip_count;
		while (counter--)
			{
			if (type == TYPE_SHORT)
				{
				if (1 != fread(&readbuf, sizeof(short), 1, tf->file))
					return Err_truncated;
				SWAPW(&readbuf.word);
				curstrip->offset = readbuf.uword;
				}
			else
				{
				if (1 != fread(&curstrip->offset, sizeof(long), 1, tf->file))
					return Err_truncated;
				SWAPD(&curstrip->offset);
				}
			++curstrip;
			}
		}

	return Success;

}
Exemplo n.º 2
0
Errcode read_filehdr(Tiff_file *tf)
/*****************************************************************************
 * read tiff file header, validate magic numbers.
 ****************************************************************************/
{
	Tifhdr	tifhdr;

	if (Success != fseek(tf->file, 0, SEEK_SET))
		return pj_errno_errcode();

	if (1 != fread(&tifhdr, sizeof(tifhdr), 1, tf->file))
		return Err_truncated;

	if (tifhdr.machine == MOTOROLA)
		tf->swap_bytes = TRUE;
	else if (tifhdr.machine == INTEL)
		tf->swap_bytes = FALSE;
	else
		return Err_bad_magic;

	SWAPW(&tifhdr.version);
	SWAPD(&tifhdr.firstifd);

	if (tifhdr.version < 42 || tifhdr.version > 59) /* we do tiff versions */
		return Err_bad_magic;						/* 4.x and 5.x only.   */

	if (tifhdr.firstifd < 8)
		return Err_bad_magic;

	tf->off_ifd_next = tifhdr.firstifd;

	return Success;
}
Exemplo n.º 3
0
static Errcode read_strip_bytecounts(Tiff_file *tf, long offset, int type, int strip_count)
/*****************************************************************************
 * load strip bytecounts into strip_data array, also remember biggest value.
 ****************************************************************************/
{
	int 		counter;
	long		highcount = 0;
	Onum		readbuf;
	Strip_data	*curstrip = tf->strip_data;

	if (NULL == curstrip)	/* we need to have offset data already or we die */
		return Err_format;

	if (strip_count != tf->strips_per_image)	/* must have same # of byte */
		return Err_format;						/* counts as we had offsets */

	if (strip_count == 1 && type == TYPE_LONG)		 /* 1 long is easy */
		{
		curstrip->size = highcount = offset;
		}
	else if (strip_count == 2 && type == TYPE_SHORT) /* 2 shorts is tricky */
		{
		convert.dword = offset;
		curstrip->offset = convert.words.word1;
		++curstrip;
		curstrip->offset = convert.words.word2;
		}
	else
		{
		if (Success != fseek(tf->file, offset, SEEK_SET))
			return pj_errno_errcode();

		counter = strip_count;
		while (counter--)
			{
			if (type == TYPE_SHORT)
				{
				if (1 != fread(&readbuf, sizeof(short), 1, tf->file))
					return Err_truncated;
				SWAPW(&readbuf);
				curstrip->size = readbuf.uword;
				}
			else
				{
				if (1 != fread(&curstrip->size, sizeof(long), 1, tf->file))
					return Err_truncated;
				SWAPD(&curstrip->size);
				}
			if (curstrip->size > highcount)
				highcount = curstrip->size;
			++curstrip;
			}
		}

	tf->longest_strip = highcount;
	return Success;

}
Exemplo n.º 4
0
int
LUfactor(Matrix A, int *indexarray)
{
    int dim = A->dim, i, j, k, i_max, k_max;
    Vector scale;
    double mx, tmp;

    scale = new_vector(dim);

    for (i = 0; i < dim; i++)
        indexarray[i] = i;

    for (i = 0; i < dim; i++) {
        mx = 0.;
        for (j = 0; j < dim; j++) {
            tmp = fabs(M_VAL(A, i, j));
            if (mx < tmp)
                mx = tmp;
        }
        scale->ve[i] = mx;
    }

    k_max = dim - 1;
    for (k = 0; k < k_max; k++) {
        mx = 0.;
        i_max = -1;
        for (i = k; i < dim; i++) {
            if (fabs(scale->ve[i]) >= Tiny * fabs(M_VAL(A, i, k))) {
                tmp = fabs(M_VAL(A, i, k)) / scale->ve[i];
                if (mx < tmp) {
                    mx = tmp;
                    i_max = i;
                }
            }
        }
        if (i_max == -1) {
            M_VAL(A, k, k) = 0.;
            continue;
        }

        if (i_max != k) {
            SWAPI(indexarray[i_max], indexarray[k]);
            for (j = 0; j < dim; j++)
                SWAPD(M_VAL(A, i_max, j), M_VAL(A, k, j));
        }

        for (i = k + 1; i < dim; i++) {
            tmp = M_VAL(A, i, k) = M_VAL(A, i, k) / M_VAL(A, k, k);
            for (j = k + 1; j < dim; j++)
                M_VAL(A, i, j) -= tmp * M_VAL(A, k, j);
        }
    }
    return 0;
}
Exemplo n.º 5
0
Errcode read_tiftags(Tiff_file *tf)
/*****************************************************************************
 * load all the tags in an ifd, save the data we care about along the way.
 *	after reading everything in the ifd, this routine attempts to fudge in
 *	any data that was missing (eg, strip offsets, strip bytecounts).  it also
 *	verifies that the required fields were present (our idea of required
 *	fields, not tiff's idea.  we require image width and height; we can fake
 *	just about anything else.)
 ****************************************************************************/
{
	Errcode err;
	short	entry_count;
	Dirent	entry;
	int 	bps_count;

	/*
	 * plug in default values for things we care about...
	 */

	tf->width = 0;
	tf->height = 0;
	tf->longest_strip = 0;
	tf->strips_per_image = 0;
	tf->planar_configuration = 1;
	tf->rows_per_strip = 0x7fffffff;
	tf->samples_per_pixel = 1;
	tf->bits_per_sample[0] = 1;
	tf->bits_per_sample[1] = 0;
	tf->bits_per_sample[2] = 0;
	tf->compression = CMPRS_NONE;
	tf->photometric = PHMET_GREY_0ISBLACK;
	tf->min_sample_value = 0;
	tf->max_sample_value = 0;	/* default will be calc'd later if needed */

	/*
	 * the saved offset of the next ifd becomes the offset to the current
	 * ifd.  we seek to that location (just in case), and load the count
	 * of entries in the ifd, which will be used as a loop counter.
	 */

	tf->off_ifd_start = tf->off_ifd_cur = tf->off_ifd_next;
	if (Success != fseek(tf->file, tf->off_ifd_cur, SEEK_SET))
		return pj_errno_errcode();
	if (1 != fread(&entry_count, sizeof(entry_count), 1, tf->file))
		return pj_errno_errcode();
	SWAPW(&entry_count);
	tf->off_ifd_cur += sizeof(entry_count);

	/*
	 * loop through all the entries (tags) in the ifd, storing off the data
	 * we care about into our own structure as we go.
	 */

	while (entry_count--)
		{
		if (Success != (err = read_next_dirent(tf, &entry)))
			return err;

		switch (entry.tag)
			{

			case TAG_IMAGE_WIDTH:

				tf->width = entry.value.word;
				break;

			case TAG_IMAGE_LENGTH:

				tf->height = entry.value.word;
				break;

			case TAG_BITS_PER_SAMPLE:

				bps_count = entry.count;
				switch (entry.count)
					{
					case 1:
						tf->bits_per_sample[0] = entry.value.word;
						if (tf->bits_per_sample[0] > 8)
							return Err_wrong_type;
						break;
					case 3:
						if (Success != fseek(tf->file, entry.value.offset, SEEK_SET))
							return pj_errno_errcode();
						if (3 != fread(tf->bits_per_sample, sizeof(short), 3, tf->file))
							return Err_truncated;
						if (tf->swap_bytes)
							{
							swapw(&tf->bits_per_sample[0]);
							swapw(&tf->bits_per_sample[1]);
							swapw(&tf->bits_per_sample[2]);
							}
						if (tf->bits_per_sample[0] != 8 ||
							tf->bits_per_sample[1] != 8 ||
							tf->bits_per_sample[2] != 8 )
							return Err_wrong_type;
						break;
					default:
						return Err_wrong_type;
					}
				break;

			case TAG_COMPRESSION:

				tf->compression = entry.value.uword;
				break;

			case TAG_PHOTOMETRIC_INTERP:

				tf->photometric = entry.value.word;
				break;

			case TAG_STRIP_OFFSETS:
			case TAG_SHORT_STRIP_OFFSETS:	/* Aldus private tag 32768 */

				if (Success != (err = read_strip_offsets(tf, entry.value.offset,
									entry.type, entry.count)))
					return err;
				break;

			case TAG_SAMPLES_PER_PIXEL:

				tf->samples_per_pixel = entry.value.word;
				switch (tf->samples_per_pixel)
					{
					case 1:
						if (tf->photometric == PHMET_RGB)
							return Err_format;
						break;
					case 3:
						tf->photometric = PHMET_RGB;	/* force RGB interp */
						break;
					default:
						return Err_wrong_type;
					}
				break;

			case TAG_ROWS_PER_STRIP:

				tf->rows_per_strip =
					(entry.type == TYPE_SHORT) ? entry.value.word : entry.value.dword;
				break;

			case TAG_STRIP_BYTE_COUNTS:

				if (Success != (err = read_strip_bytecounts(tf, entry.value.offset,
									entry.type, entry.count)))
					return err;
				break;

			case TAG_MIN_SAMPLE_VALUE:
			case TAG_MAX_SAMPLE_VALUE:
				/* we ignore these fields and calc values below.
				 * we use the min/max values to calculate greyscale
				 * pallete entries, but on the advice of of the TIFF 5.0
				 * doc ('these values should not affect the visual display
				 * of the data, they are for statistical purposes only'),
				 * we use 2**bits_per_sample instead of max_sample_value.
				 */
				 break;

			case TAG_PLANAR_CONFIG:

				tf->planar_configuration = entry.value.word;
				break;

			case TAG_COLORMAP:

				if (Success != (err = read_color_map(tf, entry.value.offset, entry.count)))
					return err;
				break;

			default:
				break;
			}
		tf->off_ifd_cur += sizeof(entry);
		}

	/*
	 * read the offset to the next ifd; we may need it for multi-image file
	 */

	if (Success != fseek(tf->file, tf->off_ifd_cur, SEEK_SET))
		return pj_errno_errcode();
	if (1 != fread(&tf->off_ifd_next, sizeof(tf->off_ifd_next), 1, tf->file))
		return Err_truncated;
	SWAPD(&tf->off_ifd_next);

	/*
	 * if we have RGB data but we only got one bits_per_sample value,
	 * propogate it to the other two entries in the array.
	 * calculate the total pixel depth.
	 */

	if (tf->photometric == PHMET_RGB && bps_count != 3)
		{
		tf->bits_per_sample[1] = tf->bits_per_sample[0];
		tf->bits_per_sample[2] = tf->bits_per_sample[0];
		}

	tf->pixel_depth = tf->bits_per_sample[0] +
					  tf->bits_per_sample[1] +
					  tf->bits_per_sample[2];

	/*
	 * calculate max_sample_value as (2**bits_per_sample)-1...
	 */

	if (tf->max_sample_value == 0)
		tf->max_sample_value = (0x01 << tf->bits_per_sample[0]) - 1;

	/*
	 * hmmm.  it seems some tif files don't have strip bytecount entries.
	 * we'll see symptoms of that here if the longest strip size is zero
	 * after reading all the tags.	when this occurs, we call a routine
	 * to calculate the byte counts.  the routine does some sanity checking
	 * and will return an error if the counts look totally unreasonable.
	 */

	if (tf->longest_strip == 0)
		if (Success != (err = calc_strip_bytecounts(tf)))
			return err;

	/*
	 * all entries in this ifd have been dealt with, make sure we have
	 * the minimum required data to run the rest of the program...
	 *	 checking strips_per_image ensures that we got strip offsets.
	 *	 checking longest_strip ensures we got (or calc'd) strip bytecounts.
	 */

	 if (tf->width == 0 ||
		 tf->height == 0 ||
		 tf->strips_per_image == 0 ||
		 tf->longest_strip == 0)
		return Err_format;


	return Success;
}
Exemplo n.º 6
0
void VariationalBayes::optimize(bool verbose,OPT_TYPE method,long maxIter,double ftol, double gtol){//{{{
   bool usedSteepest;
   long iteration=0,i,r;
   double boundOld,bound,squareNorm,squareNormOld=1,valBeta=0,valBetaDiv,natGrad_i,gradGamma_i,phiGradPhiSum_r;
   double *gradPhi,*natGrad,*gradGamma,*searchDir,*tmpD,*phiOld;
   gradPhi=natGrad=gradGamma=searchDir=tmpD=phiOld=NULL;
   MyTimer timer;
   // allocate stuff {{{
   //SimpleSparse *phiGradPhi=new SimpleSparse(beta);
   gradPhi = new double[T];
   // phiOld = new double[T]; will use gradPhi memory for this
   phiOld = NULL;
   natGrad = new double[T];
   if(method == OPTT_HS)
      gradGamma = new double[T];
   searchDir = new double[T];
   //searchDirOld = new double[T];
   //phiGradPhi_sum = new double[N];
   // }}}
#ifdef LOG_CONV
   ofstream logF(logFileName.c_str());
   logF.precision(15);
   logF<<"# iter bound squareNorm time(m) [M*means M*vars]"<<endl;
   if(logTimer)logTimer->setQuiet();
   #ifdef LONG_LOG
   vector<double> dirAlpha(M);
   #endif
#endif
   boundOld=getBound();
   timer.start();
   while(true){
      negGradient(gradPhi);
      // "yuck"
      //setVal(phiGradPhi,i,phi->val[i]*gradPhi[i]);
      //phiGradPhi->sumRows(phiGradPhi_sum);
      // removed need for phiGradPhi matrix:
      // removed need for phiGradPhi_sum
      /*for(r=0;r<N;r++){
         phiGradPhi_sum[r] = 0;
         for(i=phi->rowStart[r];i<phi->rowStart[r+1];i++) phiGradPhi_sum[r] += phi->val[i] * gradPhi[i];
      }*/

      // set natGrad & gradGamma
      squareNorm=0;
      valBeta = 0;
      valBetaDiv = 0;
      #pragma omp parallel for private(i,phiGradPhiSum_r,natGrad_i,gradGamma_i) reduction(+:squareNorm,valBeta,valBetaDiv)
      for(r=0;r<N;r++){
         phiGradPhiSum_r = 0;
         for(i = phi->rowStart[r]; i < phi->rowStart[r+1]; i++) 
            phiGradPhiSum_r += phi->val[i] * gradPhi[i];
         
         for(i = phi->rowStart[r]; i < phi->rowStart[r+1]; i++){
            natGrad_i = gradPhi[i] - phiGradPhiSum_r;
            gradGamma_i = natGrad_i * phi->val[i];
            squareNorm += natGrad_i * gradGamma_i;
            
            if(method==OPTT_PR){
               valBeta += (natGrad_i - natGrad[i])*gradGamma_i;
            }
            if(method==OPTT_HS){
               valBeta += (natGrad_i-natGrad[i])*gradGamma_i;
               valBetaDiv += (natGrad_i-natGrad[i])*gradGamma[i];
               gradGamma[i] = gradGamma_i;
            }
            natGrad[i] = natGrad_i;
         }
      }
      
      if((method==OPTT_STEEPEST) || (iteration % (N*M)==0)){
         valBeta=0;
      }else if(method==OPTT_PR ){
         // already computed:
         // valBeta=0;
         // for(i=0;i<T;i++)valBeta+= (natGrad[i]-natGradOld[i])*gradGamma[i];
         valBeta /= squareNormOld;
      }else if(method==OPTT_FR ){
         valBeta = squareNorm / squareNormOld;
      }else if(method==OPTT_HS ){
         // already computed:
         //valBeta=div=0;
         //for(i=0;i<T;i++){
         //   valBeta += (natGrad[i]-natGradOld[i])*gradGamma[i];
         //   div += (natGrad[i]-natGradOld[i])*gradGammaOld[i];
         //}
         if(valBetaDiv!=0)valBeta /= valBetaDiv;
         else valBeta = 0;
      }

      if(valBeta>0){
         usedSteepest = false;
         //for(i=0;i<T;i++)searchDir[i]= -natGrad[i] + valBeta*searchDirOld[i];
         // removed need for searchDirOld:
         #pragma omp parallel for
         for(i=0;i<T;i++)
            searchDir[i]= -natGrad[i] + valBeta*searchDir[i];
      }else{
         usedSteepest = true;
         #pragma omp parallel for
         for(i=0;i<T;i++)
            searchDir[i]= -natGrad[i];
      }

      //try conjugate step
      SWAPD(gradPhi,phiOld);
      memcpy(phiOld,phi_sm->val,T*sizeof(double)); // memcpy(phiOld,pack(),T*sizeof(double));
      unpack(phiOld,searchDir);
      bound = getBound();
      iteration++;
      // make sure there is an increase in L, else revert to steepest
      if((bound<boundOld) && (valBeta>0)){
         usedSteepest = true;
         #pragma omp parallel for
         for(i=0;i<T;i++)
            searchDir[i]= -natGrad[i];
         unpack(phiOld,searchDir);
         bound = getBound();
         // this should not be increased: iteration++;
      }
      if(bound<boundOld) { // If bound decreased even after using steepest, step back and quit.
         unpack(phiOld);
      }
      SWAPD(gradPhi,phiOld);
      if(verbose){
         #ifdef SHOW_FIXED
            messageF("iter(%c): %5.ld  bound: %.3lf grad: %.7lf  beta: %.7lf  fixed: %ld\n",(usedSteepest?'s':'o'),iteration,bound,squareNorm,valBeta,phi->countAboveDelta(0.999));
         #else
            messageF("iter(%c)[%5.lds]: %5.ld  bound: %.3lf grad: %.7lf  beta: %.7lf\n",(usedSteepest?'s':'o'),(long)timer.getTime(),iteration,bound,squareNorm,valBeta);
         #endif
      }else if(!quiet){
         messageF("\riter(%c): %5.ld  bound: %.3lf grad: %.7lf  beta: %.7lf      ",(usedSteepest?'s':'o'),iteration,bound,squareNorm,valBeta);
      }
#ifdef LOG_CONV
   if((iteration%100==0) ||
      ((iteration<500) && (iteration%50==0)) ||
      ((iteration<150) && (iteration%10==0)) ||
      ((iteration<50) && (iteration%5==0))){
      logF<<iteration<<" "<<bound<<" "<<squareNorm;
      if(logTimer)logF<<" "<<logTimer->current(0,'m');
      #ifdef LONG_LOG
      double alphaSum = 0, alphaVarNorm;
      // True 'alpha' - Dirichlet parameter is alpha+phiHat.
      for(i=1;i<M;i++){
         dirAlpha[i] = alpha[i] + phiHat[i];
         alphaSum += dirAlpha[i];
      }
      for(i=1;i<M;i++)logF<< " " << dirAlpha[i] / alphaSum;
      alphaVarNorm = alphaSum*alphaSum*(alphaSum+1);
      for(i=1;i<M;i++)logF<<" "<<dirAlpha[i]*(alphaSum-dirAlpha[i])/alphaVarNorm;
      #endif
      logF<<endl;
   }
#endif

      // convergence check {{{
      if(bound<boundOld){
         message("\nEnd: bound decrease\n");
         break;
      }
      if(abs(bound-boundOld)<=ftol){
         message("\nEnd: converged (ftol)\n");
         break;
      }
      if(squareNorm<=gtol){
         message("\nEnd: converged (gtol)\n");
         break;
      }
      if(iteration>=maxIter){
         message("\nEnd: maxIter exceeded\n");
         break;
      }
      // }}}
      // store essentials {{{
      squareNormOld=squareNorm;
      boundOld=bound;
      // }}}
      R_INTERUPT;
   }
   if(quiet){
      messageF("iter(%c): %5.ld  bound: %.3lf grad: %.7lf  beta: %.7lf\n",(usedSteepest?'s':'o'),iteration,bound,squareNorm,valBeta);
   }
#ifdef LOG_CONV
   logF<<iteration<<" "<<bound<<" "<<squareNorm;
   if(logTimer)logF<<" "<<logTimer->current(0,'m');
   #ifdef LONG_LOG
   double alphaSum = 0, alphaVarNorm;
   // True 'alpha' - Dirichlet parameter is alpha+phiHat.
   for(i=1;i<M;i++){
      dirAlpha[i] = alpha[i] + phiHat[i];
      alphaSum += dirAlpha[i];
   }
   for(i=1;i<M;i++)logF<< " " << dirAlpha[i] / alphaSum;
   alphaVarNorm = alphaSum*alphaSum*(alphaSum+1);
   for(i=1;i<M;i++)logF<<" "<<dirAlpha[i]*(alphaSum-dirAlpha[i])/alphaVarNorm;
   #endif
   logF<<endl;
   if(logTimer)logTimer->setVerbose();
   logF.close();
#endif
   // free memory {{{
   //delete phiGradPhi;
   delete[] gradPhi;
   delete[] natGrad;
   if(method == OPTT_HS)
      delete[] gradGamma;
   delete[] searchDir;
   //delete[] searchDirOld;
   //delete[] phiGradPhi_sum;
   // }}}
}//}}}
Exemplo n.º 7
0
/*
 * FatGetFatEntry()
 * returns the Fat entry for a given cluster number
 */
BOOLEAN FatGetFatEntry(PFAT_VOLUME_INFO Volume, ULONG Cluster, ULONG* ClusterPointer)
{
	ULONG		fat = 0;
	UINT32		FatOffset;
	UINT32		ThisFatSecNum;
	UINT32		ThisFatEntOffset;

	//TRACE("FatGetFatEntry() Retrieving FAT entry for cluster %d.\n", Cluster);

	switch(Volume->FatType)
	{
	case FAT12:

		FatOffset = Cluster + (Cluster / 2);
		ThisFatSecNum = Volume->ActiveFatSectorStart + (FatOffset / Volume->BytesPerSector);
		ThisFatEntOffset = (FatOffset % Volume->BytesPerSector);

		TRACE("FatOffset: %d\n", FatOffset);
		TRACE("ThisFatSecNum: %d\n", ThisFatSecNum);
		TRACE("ThisFatEntOffset: %d\n", ThisFatEntOffset);

		if (ThisFatEntOffset == (Volume->BytesPerSector - 1))
		{
			if (!FatReadVolumeSectors(Volume, ThisFatSecNum, 2, (PVOID)FILESYSBUFFER))
			{
				return FALSE;
			}
		}
		else
		{
			if (!FatReadVolumeSectors(Volume, ThisFatSecNum, 1, (PVOID)FILESYSBUFFER))
			{
				return FALSE;
			}
		}

		fat = *((USHORT *) ((ULONG_PTR)FILESYSBUFFER + ThisFatEntOffset));
		fat = SWAPW(fat);
		if (Cluster & 0x0001)
			fat = fat >> 4;	/* Cluster number is ODD */
		else
			fat = fat & 0x0FFF;	/* Cluster number is EVEN */

		break;

	case FAT16:
	case FATX16:

		FatOffset = (Cluster * 2);
		ThisFatSecNum = Volume->ActiveFatSectorStart + (FatOffset / Volume->BytesPerSector);
		ThisFatEntOffset = (FatOffset % Volume->BytesPerSector);

		if (!FatReadVolumeSectors(Volume, ThisFatSecNum, 1, (PVOID)FILESYSBUFFER))
		{
			return FALSE;
		}

		fat = *((USHORT *) ((ULONG_PTR)FILESYSBUFFER + ThisFatEntOffset));
		fat = SWAPW(fat);

		break;

	case FAT32:
	case FATX32:

		FatOffset = (Cluster * 4);
		ThisFatSecNum = Volume->ActiveFatSectorStart + (FatOffset / Volume->BytesPerSector);
		ThisFatEntOffset = (FatOffset % Volume->BytesPerSector);

		if (!FatReadVolumeSectors(Volume, ThisFatSecNum, 1, (PVOID)FILESYSBUFFER))
		{
			return FALSE;
		}

		// Get the fat entry
		fat = (*((ULONG *) ((ULONG_PTR)FILESYSBUFFER + ThisFatEntOffset))) & 0x0FFFFFFF;
		fat = SWAPD(fat);

		break;

	default:
		TRACE("Unknown FAT type %d\n", Volume->FatType);
		return FALSE;

	}
Exemplo n.º 8
0
ULONG FatDetermineFatType(PFAT_BOOTSECTOR FatBootSector, ULONGLONG PartitionSectorCount)
{
	ULONG			RootDirSectors;
	ULONG			DataSectorCount;
	ULONG			SectorsPerFat;
	ULONG			TotalSectors;
	ULONG			CountOfClusters;
	PFAT32_BOOTSECTOR	Fat32BootSector = (PFAT32_BOOTSECTOR)FatBootSector;
	PFATX_BOOTSECTOR	FatXBootSector = (PFATX_BOOTSECTOR)FatBootSector;

	if (0 == strncmp(FatXBootSector->FileSystemType, "FATX", 4))
	{
		CountOfClusters = (ULONG)(PartitionSectorCount / FatXBootSector->SectorsPerCluster);
		if (CountOfClusters < 65525)
		{
			/* Volume is FATX16 */
			return FATX16;
		}
		else
		{
			/* Volume is FAT32 */
			return FATX32;
		}
	}
	else
	{
		RootDirSectors = ((SWAPW(FatBootSector->RootDirEntries) * 32) + (SWAPW(FatBootSector->BytesPerSector) - 1)) / SWAPW(FatBootSector->BytesPerSector);
		SectorsPerFat = SWAPW(FatBootSector->SectorsPerFat) ? SWAPW(FatBootSector->SectorsPerFat) : SWAPD(Fat32BootSector->SectorsPerFatBig);
		TotalSectors = SWAPW(FatBootSector->TotalSectors) ? SWAPW(FatBootSector->TotalSectors) : SWAPD(FatBootSector->TotalSectorsBig);
		DataSectorCount = TotalSectors - (SWAPW(FatBootSector->ReservedSectors) + (FatBootSector->NumberOfFats * SectorsPerFat) + RootDirSectors);

//mjl
		if (FatBootSector->SectorsPerCluster == 0)
			CountOfClusters = 0;
		else
			CountOfClusters = DataSectorCount / FatBootSector->SectorsPerCluster;

		if (CountOfClusters < 4085)
		{
			/* Volume is FAT12 */
			return FAT12;
		}
		else if (CountOfClusters < 65525)
		{
			/* Volume is FAT16 */
			return FAT16;
		}
		else
		{
			/* Volume is FAT32 */
			return FAT32;
		}
	}
}
Exemplo n.º 9
0
BOOLEAN FatOpenVolume(PFAT_VOLUME_INFO Volume, PFAT_BOOTSECTOR BootSector, ULONGLONG PartitionSectorCount)
{
	char ErrMsg[80];
	ULONG FatSize;
	PFAT_BOOTSECTOR	FatVolumeBootSector;
	PFAT32_BOOTSECTOR Fat32VolumeBootSector;
	PFATX_BOOTSECTOR FatXVolumeBootSector;

	TRACE("FatOpenVolume() DeviceId = %d\n", Volume->DeviceId);

	//
	// Allocate the memory to hold the boot sector
	//
	FatVolumeBootSector = (PFAT_BOOTSECTOR)BootSector;
	Fat32VolumeBootSector = (PFAT32_BOOTSECTOR)BootSector;
	FatXVolumeBootSector = (PFATX_BOOTSECTOR)BootSector;

	// Get the FAT type
	Volume->FatType = FatDetermineFatType(FatVolumeBootSector, PartitionSectorCount);

	// Dump boot sector (and swap it for big endian systems)
	TRACE("Dumping boot sector:\n");
	if (ISFATX(Volume->FatType))
	{
		FatSwapFatXBootSector(FatXVolumeBootSector);
		TRACE("sizeof(FATX_BOOTSECTOR) = 0x%x.\n", sizeof(FATX_BOOTSECTOR));

		TRACE("FileSystemType: %c%c%c%c.\n", FatXVolumeBootSector->FileSystemType[0], FatXVolumeBootSector->FileSystemType[1], FatXVolumeBootSector->FileSystemType[2], FatXVolumeBootSector->FileSystemType[3]);
		TRACE("VolumeSerialNumber: 0x%x\n", FatXVolumeBootSector->VolumeSerialNumber);
		TRACE("SectorsPerCluster: %d\n", FatXVolumeBootSector->SectorsPerCluster);
		TRACE("NumberOfFats: %d\n", FatXVolumeBootSector->NumberOfFats);
		TRACE("Unknown: 0x%x\n", FatXVolumeBootSector->Unknown);

		TRACE("FatType %s\n", Volume->FatType == FATX16 ? "FATX16" : "FATX32");

	}
	else if (Volume->FatType == FAT32)
	{
		FatSwapFat32BootSector(Fat32VolumeBootSector);
		TRACE("sizeof(FAT32_BOOTSECTOR) = 0x%x.\n", sizeof(FAT32_BOOTSECTOR));

		TRACE("JumpBoot: 0x%x 0x%x 0x%x\n", Fat32VolumeBootSector->JumpBoot[0], Fat32VolumeBootSector->JumpBoot[1], Fat32VolumeBootSector->JumpBoot[2]);
		TRACE("OemName: %c%c%c%c%c%c%c%c\n", Fat32VolumeBootSector->OemName[0], Fat32VolumeBootSector->OemName[1], Fat32VolumeBootSector->OemName[2], Fat32VolumeBootSector->OemName[3], Fat32VolumeBootSector->OemName[4], Fat32VolumeBootSector->OemName[5], Fat32VolumeBootSector->OemName[6], Fat32VolumeBootSector->OemName[7]);
		TRACE("BytesPerSector: %d\n", Fat32VolumeBootSector->BytesPerSector);
		TRACE("SectorsPerCluster: %d\n", Fat32VolumeBootSector->SectorsPerCluster);
		TRACE("ReservedSectors: %d\n", Fat32VolumeBootSector->ReservedSectors);
		TRACE("NumberOfFats: %d\n", Fat32VolumeBootSector->NumberOfFats);
		TRACE("RootDirEntries: %d\n", Fat32VolumeBootSector->RootDirEntries);
		TRACE("TotalSectors: %d\n", Fat32VolumeBootSector->TotalSectors);
		TRACE("MediaDescriptor: 0x%x\n", Fat32VolumeBootSector->MediaDescriptor);
		TRACE("SectorsPerFat: %d\n", Fat32VolumeBootSector->SectorsPerFat);
		TRACE("SectorsPerTrack: %d\n", Fat32VolumeBootSector->SectorsPerTrack);
		TRACE("NumberOfHeads: %d\n", Fat32VolumeBootSector->NumberOfHeads);
		TRACE("HiddenSectors: %d\n", Fat32VolumeBootSector->HiddenSectors);
		TRACE("TotalSectorsBig: %d\n", Fat32VolumeBootSector->TotalSectorsBig);
		TRACE("SectorsPerFatBig: %d\n", Fat32VolumeBootSector->SectorsPerFatBig);
		TRACE("ExtendedFlags: 0x%x\n", Fat32VolumeBootSector->ExtendedFlags);
		TRACE("FileSystemVersion: 0x%x\n", Fat32VolumeBootSector->FileSystemVersion);
		TRACE("RootDirStartCluster: %d\n", Fat32VolumeBootSector->RootDirStartCluster);
		TRACE("FsInfo: %d\n", Fat32VolumeBootSector->FsInfo);
		TRACE("BackupBootSector: %d\n", Fat32VolumeBootSector->BackupBootSector);
		TRACE("Reserved: 0x%x\n", Fat32VolumeBootSector->Reserved);
		TRACE("DriveNumber: 0x%x\n", Fat32VolumeBootSector->DriveNumber);
		TRACE("Reserved1: 0x%x\n", Fat32VolumeBootSector->Reserved1);
		TRACE("BootSignature: 0x%x\n", Fat32VolumeBootSector->BootSignature);
		TRACE("VolumeSerialNumber: 0x%x\n", Fat32VolumeBootSector->VolumeSerialNumber);
		TRACE("VolumeLabel: %c%c%c%c%c%c%c%c%c%c%c\n", Fat32VolumeBootSector->VolumeLabel[0], Fat32VolumeBootSector->VolumeLabel[1], Fat32VolumeBootSector->VolumeLabel[2], Fat32VolumeBootSector->VolumeLabel[3], Fat32VolumeBootSector->VolumeLabel[4], Fat32VolumeBootSector->VolumeLabel[5], Fat32VolumeBootSector->VolumeLabel[6], Fat32VolumeBootSector->VolumeLabel[7], Fat32VolumeBootSector->VolumeLabel[8], Fat32VolumeBootSector->VolumeLabel[9], Fat32VolumeBootSector->VolumeLabel[10]);
		TRACE("FileSystemType: %c%c%c%c%c%c%c%c\n", Fat32VolumeBootSector->FileSystemType[0], Fat32VolumeBootSector->FileSystemType[1], Fat32VolumeBootSector->FileSystemType[2], Fat32VolumeBootSector->FileSystemType[3], Fat32VolumeBootSector->FileSystemType[4], Fat32VolumeBootSector->FileSystemType[5], Fat32VolumeBootSector->FileSystemType[6], Fat32VolumeBootSector->FileSystemType[7]);
		TRACE("BootSectorMagic: 0x%x\n", Fat32VolumeBootSector->BootSectorMagic);
	}
	else
	{
		FatSwapFatBootSector(FatVolumeBootSector);
		TRACE("sizeof(FAT_BOOTSECTOR) = 0x%x.\n", sizeof(FAT_BOOTSECTOR));

		TRACE("JumpBoot: 0x%x 0x%x 0x%x\n", FatVolumeBootSector->JumpBoot[0], FatVolumeBootSector->JumpBoot[1], FatVolumeBootSector->JumpBoot[2]);
		TRACE("OemName: %c%c%c%c%c%c%c%c\n", FatVolumeBootSector->OemName[0], FatVolumeBootSector->OemName[1], FatVolumeBootSector->OemName[2], FatVolumeBootSector->OemName[3], FatVolumeBootSector->OemName[4], FatVolumeBootSector->OemName[5], FatVolumeBootSector->OemName[6], FatVolumeBootSector->OemName[7]);
		TRACE("BytesPerSector: %d\n", FatVolumeBootSector->BytesPerSector);
		TRACE("SectorsPerCluster: %d\n", FatVolumeBootSector->SectorsPerCluster);
		TRACE("ReservedSectors: %d\n", FatVolumeBootSector->ReservedSectors);
		TRACE("NumberOfFats: %d\n", FatVolumeBootSector->NumberOfFats);
		TRACE("RootDirEntries: %d\n", FatVolumeBootSector->RootDirEntries);
		TRACE("TotalSectors: %d\n", FatVolumeBootSector->TotalSectors);
		TRACE("MediaDescriptor: 0x%x\n", FatVolumeBootSector->MediaDescriptor);
		TRACE("SectorsPerFat: %d\n", FatVolumeBootSector->SectorsPerFat);
		TRACE("SectorsPerTrack: %d\n", FatVolumeBootSector->SectorsPerTrack);
		TRACE("NumberOfHeads: %d\n", FatVolumeBootSector->NumberOfHeads);
		TRACE("HiddenSectors: %d\n", FatVolumeBootSector->HiddenSectors);
		TRACE("TotalSectorsBig: %d\n", FatVolumeBootSector->TotalSectorsBig);
		TRACE("DriveNumber: 0x%x\n", FatVolumeBootSector->DriveNumber);
		TRACE("Reserved1: 0x%x\n", FatVolumeBootSector->Reserved1);
		TRACE("BootSignature: 0x%x\n", FatVolumeBootSector->BootSignature);
		TRACE("VolumeSerialNumber: 0x%x\n", FatVolumeBootSector->VolumeSerialNumber);
		TRACE("VolumeLabel: %c%c%c%c%c%c%c%c%c%c%c\n", FatVolumeBootSector->VolumeLabel[0], FatVolumeBootSector->VolumeLabel[1], FatVolumeBootSector->VolumeLabel[2], FatVolumeBootSector->VolumeLabel[3], FatVolumeBootSector->VolumeLabel[4], FatVolumeBootSector->VolumeLabel[5], FatVolumeBootSector->VolumeLabel[6], FatVolumeBootSector->VolumeLabel[7], FatVolumeBootSector->VolumeLabel[8], FatVolumeBootSector->VolumeLabel[9], FatVolumeBootSector->VolumeLabel[10]);
		TRACE("FileSystemType: %c%c%c%c%c%c%c%c\n", FatVolumeBootSector->FileSystemType[0], FatVolumeBootSector->FileSystemType[1], FatVolumeBootSector->FileSystemType[2], FatVolumeBootSector->FileSystemType[3], FatVolumeBootSector->FileSystemType[4], FatVolumeBootSector->FileSystemType[5], FatVolumeBootSector->FileSystemType[6], FatVolumeBootSector->FileSystemType[7]);
		TRACE("BootSectorMagic: 0x%x\n", FatVolumeBootSector->BootSectorMagic);
	}

	//
	// Check the boot sector magic
	//
	if (! ISFATX(Volume->FatType) && FatVolumeBootSector->BootSectorMagic != 0xaa55)
	{
		sprintf(ErrMsg, "Invalid boot sector magic (expected 0xaa55 found 0x%x)",
		        FatVolumeBootSector->BootSectorMagic);
		FileSystemError(ErrMsg);
		return FALSE;
	}

	//
	// Check the FAT cluster size
	// We do not support clusters bigger than 64k
	//
	if ((ISFATX(Volume->FatType) && 64 * 1024 < FatXVolumeBootSector->SectorsPerCluster * 512) ||
	   (! ISFATX(Volume->FatType) && 64 * 1024 < FatVolumeBootSector->SectorsPerCluster * FatVolumeBootSector->BytesPerSector))
	{
		FileSystemError("This file system has cluster sizes bigger than 64k.\nFreeLoader does not support this.");
		return FALSE;
	}

	//
	// Get the sectors per FAT,
	// root directory starting sector,
	// and data sector start
	//
	if (ISFATX(Volume->FatType))
	{
		Volume->BytesPerSector = 512;
		Volume->SectorsPerCluster = SWAPD(FatXVolumeBootSector->SectorsPerCluster);
		Volume->FatSectorStart = (4096 / Volume->BytesPerSector);
		Volume->ActiveFatSectorStart = Volume->FatSectorStart;
		Volume->NumberOfFats = 1;
		FatSize = (ULONG)(PartitionSectorCount / Volume->SectorsPerCluster *
		          (Volume->FatType == FATX16 ? 2 : 4));
		Volume->SectorsPerFat = (((FatSize + 4095) / 4096) * 4096) / Volume->BytesPerSector;

		Volume->RootDirSectorStart = Volume->FatSectorStart + Volume->NumberOfFats * Volume->SectorsPerFat;
		Volume->RootDirSectors = FatXVolumeBootSector->SectorsPerCluster;

		Volume->DataSectorStart = Volume->RootDirSectorStart + Volume->RootDirSectors;
	}
	else if (Volume->FatType != FAT32)
	{
		Volume->BytesPerSector = FatVolumeBootSector->BytesPerSector;
		Volume->SectorsPerCluster = FatVolumeBootSector->SectorsPerCluster;
		Volume->FatSectorStart = FatVolumeBootSector->ReservedSectors;
		Volume->ActiveFatSectorStart = Volume->FatSectorStart;
		Volume->NumberOfFats = FatVolumeBootSector->NumberOfFats;
		Volume->SectorsPerFat = FatVolumeBootSector->SectorsPerFat;

		Volume->RootDirSectorStart = Volume->FatSectorStart + Volume->NumberOfFats * Volume->SectorsPerFat;
		Volume->RootDirSectors = ((FatVolumeBootSector->RootDirEntries * 32) + (Volume->BytesPerSector - 1)) / Volume->BytesPerSector;

		Volume->DataSectorStart = Volume->RootDirSectorStart + Volume->RootDirSectors;
	}
	else
	{
		Volume->BytesPerSector = Fat32VolumeBootSector->BytesPerSector;
		Volume->SectorsPerCluster = Fat32VolumeBootSector->SectorsPerCluster;
		Volume->FatSectorStart = Fat32VolumeBootSector->ReservedSectors;
		Volume->ActiveFatSectorStart = Volume->FatSectorStart +
		                               ((Fat32VolumeBootSector->ExtendedFlags & 0x80) ? ((Fat32VolumeBootSector->ExtendedFlags & 0x0f) * Fat32VolumeBootSector->SectorsPerFatBig) : 0);
		Volume->NumberOfFats = Fat32VolumeBootSector->NumberOfFats;
		Volume->SectorsPerFat = Fat32VolumeBootSector->SectorsPerFatBig;

		Volume->RootDirStartCluster = Fat32VolumeBootSector->RootDirStartCluster;
		Volume->DataSectorStart = Volume->FatSectorStart + Volume->NumberOfFats * Volume->SectorsPerFat;

		//
		// Check version
		// we only work with version 0
		//
		if (Fat32VolumeBootSector->FileSystemVersion != 0)
		{
			FileSystemError("FreeLoader is too old to work with this FAT32 filesystem.\nPlease update FreeLoader.");
			return FALSE;
		}
	}

	return TRUE;
}
Exemplo n.º 10
0
void ENCONCAT(stack& s) {
    SWAPD(s);
    CONS(s);
    CONCAT(s);
}