OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id)
{
	/* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */
	static const char module[]="OJPEGReadHeaderInfoSecStreamSof";
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint16 m;
	uint16 n;
	uint8 o;
	uint16 p;
	uint16 q;
	if (sp->sof_log!=0)
	{
		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JPEG data");
		return(0);
	}
	if (sp->subsamplingcorrect==0)
		sp->sof_marker_id=marker_id;
	/* Lf: data length */
	if (OJPEGReadWord(sp,&m)==0)
		return(0);
	if (m<11)
	{
		if (sp->subsamplingcorrect==0)
			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
		return(0);
	}
	m-=8;
	if (m%3!=0)
	{
		if (sp->subsamplingcorrect==0)
			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
		return(0);
	}
	n=m/3;
	if (sp->subsamplingcorrect==0)
	{
		if (n!=sp->samples_per_pixel)
		{
			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected number of samples");
			return(0);
		}
	}
	/* P: Sample precision */
	if (OJPEGReadByte(sp,&o)==0)
		return(0);
	if (o!=8)
	{
		if (sp->subsamplingcorrect==0)
			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected number of bits per sample");
		return(0);
	}
	/* Y: Number of lines, X: Number of samples per line */
	if (sp->subsamplingcorrect)
		OJPEGReadSkip(sp,4);
	else
	{
		/* Y: Number of lines */
		if (OJPEGReadWord(sp,&p)==0)
			return(0);
		if (((uint32)p<sp->image_length) && ((uint32)p<sp->strile_length_total))
		{
			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected height");
			return(0);
		}
		sp->sof_y=p;
		/* X: Number of samples per line */
		if (OJPEGReadWord(sp,&p)==0)
			return(0);
		if (((uint32)p<sp->image_width) && ((uint32)p<sp->strile_width))
		{
			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected width");
			return(0);
		}
		if ((uint32)p>sp->strile_width)
		{
			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data image width exceeds expected image width");
			return(0);
		}
		sp->sof_x=p;
	}
	/* Nf: Number of image components in frame */
	if (OJPEGReadByte(sp,&o)==0)
		return(0);
	if (o!=n)
	{
		if (sp->subsamplingcorrect==0)
			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
		return(0);
	}
	/* per component stuff */
	/* TODO: double-check that flow implies that n cannot be as big as to make us overflow sof_c, sof_hv and sof_tq arrays */
	for (q=0; q<n; q++)
	{
		/* C: Component identifier */
		if (OJPEGReadByte(sp,&o)==0)
			return(0);
		if (sp->subsamplingcorrect==0)
			sp->sof_c[q]=o;
		/* H: Horizontal sampling factor, and V: Vertical sampling factor */
		if (OJPEGReadByte(sp,&o)==0)
			return(0);
		if (sp->subsamplingcorrect!=0)
		{
			if (q==0)
			{
				sp->subsampling_hor=(o>>4);
				sp->subsampling_ver=(o&15);
				if (((sp->subsampling_hor!=1) && (sp->subsampling_hor!=2) && (sp->subsampling_hor!=4)) ||
					((sp->subsampling_ver!=1) && (sp->subsampling_ver!=2) && (sp->subsampling_ver!=4)))
					sp->subsampling_force_desubsampling_inside_decompression=1;
			}
			else
			{
				if (o!=17)
					sp->subsampling_force_desubsampling_inside_decompression=1;
			}
		}
		else
		{
			sp->sof_hv[q]=o;
			if (sp->subsampling_force_desubsampling_inside_decompression==0)
			{
				if (q==0)
				{
					if (o!=((sp->subsampling_hor<<4)|sp->subsampling_ver))
					{
						TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected subsampling values");
						return(0);
					}
				}
				else
				{
					if (o!=17)
					{
						TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected subsampling values");
						return(0);
					}
				}
			}
		}
		/* Tq: Quantization table destination selector */
		if (OJPEGReadByte(sp,&o)==0)
			return(0);
		if (sp->subsamplingcorrect==0)
			sp->sof_tq[q]=o;
	}
	if (sp->subsamplingcorrect==0)
		sp->sof_log=1;
	return(1);
}