Пример #1
0
/*
 * Compute the # bytes in a variable height, row-aligned strip.
 */
tsize_t
TIFFVStripSize(TIFF* tif, uint32 nrows)
{
	TIFFDirectory *td = &tif->tif_dir;

	if (nrows == (uint32) -1)
		nrows = td->td_imagelength;
#ifdef YCBCR_SUPPORT
	if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
	    td->td_photometric == PHOTOMETRIC_YCBCR &&
	    !isUpSampled(tif)) {
		/*
		 * Packed YCbCr data contain one Cb+Cr for every
		 * HorizontalSampling*VerticalSampling Y values.
		 * Must also roundup width and height when calculating
		 * since images that are not a multiple of the
		 * horizontal/vertical subsampling area include
		 * YCbCr data for the extended image.
		 */
		tsize_t w =
		    TIFFroundup(td->td_imagewidth, td->td_ycbcrsubsampling[0]);
		tsize_t scanline = TIFFhowmany(w*td->td_bitspersample, 8);
		tsize_t samplingarea =
		    td->td_ycbcrsubsampling[0]*td->td_ycbcrsubsampling[1];
		nrows = TIFFroundup(nrows, td->td_ycbcrsubsampling[1]);
		/* NB: don't need TIFFhowmany here 'cuz everything is rounded */
		return ((tsize_t)
		    (nrows*scanline + 2*(nrows*scanline / samplingarea)));
	} else
#endif
		return ((tsize_t)(nrows * TIFFScanlineSize(tif)));
}
Пример #2
0
/*
 * Return the number of bytes to read/write in a call to
 * one of the scanline-oriented i/o routines.  Note that
 * this number may be 1/samples-per-pixel if data is
 * stored as separate planes.
 * The ScanlineSize in case of YCbCrSubsampling is defined as the
 * strip size divided by the strip height, i.e. the size of a pack of vertical
 * subsampling lines divided by vertical subsampling. It should thus make
 * sense when multiplied by a multiple of vertical subsampling.
 */
uint64
TIFFScanlineSize64(TIFF* tif)
{
	static const char module[] = "TIFFScanlineSize64";
	TIFFDirectory *td = &tif->tif_dir;
	uint64 scanline_size;
	if (td->td_planarconfig==PLANARCONFIG_CONTIG)
	{
		if ((td->td_photometric==PHOTOMETRIC_YCBCR)&&
		    (td->td_samplesperpixel==3)&&
		    (!isUpSampled(tif)))
		{
			uint16 ycbcrsubsampling[2];
			uint16 samplingblock_samples;
			uint32 samplingblocks_hor;
			uint64 samplingrow_samples;
			uint64 samplingrow_size;
			if(td->td_samplesperpixel!=3)
			{
                            TIFFErrorExt(tif->tif_clientdata,module,
                                         "Invalid td_samplesperpixel value");
                            return 0;
			}
			TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,
                                              ycbcrsubsampling+0,
                                              ycbcrsubsampling+1);
			if (((ycbcrsubsampling[0]!=1)&&(ycbcrsubsampling[0]!=2)&&(ycbcrsubsampling[0]!=4)) ||
			    ((ycbcrsubsampling[1]!=1)&&(ycbcrsubsampling[1]!=2)&&(ycbcrsubsampling[1]!=4)))
			{
                            TIFFErrorExt(tif->tif_clientdata,module,
                                         "Invalid YCbCr subsampling");
                            return 0;
			}
			samplingblock_samples = ycbcrsubsampling[0]*ycbcrsubsampling[1]+2;
			samplingblocks_hor = TIFFhowmany_32(td->td_imagewidth,ycbcrsubsampling[0]);
			samplingrow_samples = _TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module);
			samplingrow_size = TIFFhowmany_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module),8);
/* IMLIB			scanline_size = (samplingrow_size/ycbcrsubsampling[1]);   See tif_jpeg.c */
			scanline_size = samplingrow_size;
		}
		else
		{
			uint64 scanline_samples;
			scanline_samples=_TIFFMultiply64(tif,td->td_imagewidth,td->td_samplesperpixel,module);
			scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,scanline_samples,td->td_bitspersample,module),8);
		}
	}
	else
        {
		scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,td->td_imagewidth,td->td_bitspersample,module),8);
        }
        if (scanline_size == 0)
        {
                TIFFErrorExt(tif->tif_clientdata,module,"Computed scanline size is zero");
                return 0;
        }
	return(scanline_size);
}
Пример #3
0
/*
 * Compute the # bytes in a variable height, row-aligned strip.
 */
uint64
TIFFVStripSize64(TIFF* tif, uint32 nrows)
{
	static const char module[] = "TIFFVStripSize64";
	TIFFDirectory *td = &tif->tif_dir;
	if (nrows==(uint32)(-1))
		nrows=td->td_imagelength;
	if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&&
	    (td->td_photometric == PHOTOMETRIC_YCBCR)&&
	    (!isUpSampled(tif)))
	{
		/*
		 * Packed YCbCr data contain one Cb+Cr for every
		 * HorizontalSampling*VerticalSampling Y values.
		 * Must also roundup width and height when calculating
		 * since images that are not a multiple of the
		 * horizontal/vertical subsampling area include
		 * YCbCr data for the extended image.
		 */
		uint16 ycbcrsubsampling[2];
		uint16 samplingblock_samples;
		uint32 samplingblocks_hor;
		uint32 samplingblocks_ver;
		uint64 samplingrow_samples;
		uint64 samplingrow_size;
		if(td->td_samplesperpixel!=3)
		{
			TIFFErrorExt(tif->tif_clientdata,module,
			    "Invalid td_samplesperpixel value");
			return 0;
		}
		TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0,
		    ycbcrsubsampling+1);
		if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4)
		    ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4))
		{
			TIFFErrorExt(tif->tif_clientdata,module,
				     "Invalid YCbCr subsampling (%dx%d)",
				     ycbcrsubsampling[0],
				     ycbcrsubsampling[1] );
			return 0;
		}
		samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2;
		samplingblocks_hor=TIFFhowmany_32(td->td_imagewidth,ycbcrsubsampling[0]);
		samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]);
		samplingrow_samples=_TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module);
		samplingrow_size=TIFFhowmany8_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module));
		return(_TIFFMultiply64(tif,samplingrow_size,samplingblocks_ver,module));
	}
	else
		return(_TIFFMultiply64(tif,nrows,TIFFScanlineSize64(tif),module));
}
Пример #4
0
/*
 * Compute the # bytes in a variable height, row-aligned strip.
 */
tsize_t
TIFFVStripSize(TIFF* tif, uint32 nrows)
{
	TIFFDirectory *td = &tif->tif_dir;

	if (nrows == (uint32) -1)
		nrows = td->td_imagelength;
	if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
	    td->td_photometric == PHOTOMETRIC_YCBCR &&
	    !isUpSampled(tif)) {
		/*
		 * Packed YCbCr data contain one Cb+Cr for every
		 * HorizontalSampling*VerticalSampling Y values.
		 * Must also roundup width and height when calculating
		 * since images that are not a multiple of the
		 * horizontal/vertical subsampling area include
		 * YCbCr data for the extended image.
		 */
                uint16 ycbcrsubsampling[2];
                tsize_t w, scanline, samplingarea;
		ycbcrsubsampling[0] = 0;
		ycbcrsubsampling[1] = 0;

                TIFFGetField( tif, TIFFTAG_YCBCRSUBSAMPLING, 
                              ycbcrsubsampling + 0, 
                              ycbcrsubsampling + 1 );
		/* make sure we dont get division by 0 due to bad tiffs */
		if (!ycbcrsubsampling[0]) ycbcrsubsampling[0] = 1;
		if (!ycbcrsubsampling[1]) ycbcrsubsampling[1] = 1;

		samplingarea = ycbcrsubsampling[0]*ycbcrsubsampling[1];
		if (samplingarea == 0) {
			_TIFFError(tif, tif->tif_name,
				"Invalid YCbCr subsampling");
			return 0;
		}

		w = TIFFroundup(td->td_imagewidth, ycbcrsubsampling[0]);
		scanline = TIFFhowmany8(multiply(tif, w, td->td_bitspersample,
						 "TIFFVStripSize"));
		nrows = TIFFroundup(nrows, ycbcrsubsampling[1]);
		/* NB: don't need TIFFhowmany here 'cuz everything is rounded */
		scanline = multiply(tif, nrows, scanline, "TIFFVStripSize");
		return ((tsize_t)
		    summarize(tif, scanline,
			      multiply(tif, 2, scanline / samplingarea,
				       "TIFFVStripSize"), "TIFFVStripSize"));
	} else
		return ((tsize_t) multiply(tif, nrows, TIFFScanlineSize(tif),
					   "TIFFVStripSize"));
}
Пример #5
0
/*
 * Compute the # bytes in a variable length, row-aligned tile.
 */
tsize_t
TIFFVTileSize(TIFF* tif, uint32 nrows)
{
	TIFFDirectory *td = &tif->tif_dir;
	tsize_t tilesize;

	if (td->td_tilelength == 0 || td->td_tilewidth == 0 ||
	    td->td_tiledepth == 0)
		return ((tsize_t) 0);
	if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
	    td->td_photometric == PHOTOMETRIC_YCBCR &&
	    !isUpSampled(tif)) {
		/*
		 * Packed YCbCr data contain one Cb+Cr for every
		 * HorizontalSampling*VerticalSampling Y values.
		 * Must also roundup width and height when calculating
		 * since images that are not a multiple of the
		 * horizontal/vertical subsampling area include
		 * YCbCr data for the extended image.
		 */
		tsize_t w =
		    TIFFroundup(td->td_tilewidth, td->td_ycbcrsubsampling[0]);
		tsize_t rowsize =
		    TIFFhowmany8(multiply(tif, w, td->td_bitspersample,
					  "TIFFVTileSize"));
		tsize_t samplingarea =
		    td->td_ycbcrsubsampling[0]*td->td_ycbcrsubsampling[1];
		if (samplingarea == 0) {
			TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Invalid YCbCr subsampling");
			return 0;
		}
		nrows = TIFFroundup(nrows, td->td_ycbcrsubsampling[1]);
		/* NB: don't need TIFFhowmany here 'cuz everything is rounded */
		tilesize = multiply(tif, nrows, rowsize, "TIFFVTileSize");
		tilesize = summarize(tif, tilesize,
				     multiply(tif, 2, tilesize / samplingarea,
					      "TIFFVTileSize"),
				     "TIFFVTileSize");
	} else
		tilesize = multiply(tif, nrows, TIFFTileRowSize(tif),
				    "TIFFVTileSize");
	return ((tsize_t)
	    multiply(tif, tilesize, td->td_tiledepth, "TIFFVTileSize"));
}
Пример #6
0
/*
 * Return the number of bytes to read/write in a call to
 * one of the scanline-oriented i/o routines.  Note that
 * this number may be 1/samples-per-pixel if data is
 * stored as separate planes.
 */
tsize_t
TIFFScanlineSize(TIFF* tif)
{
	TIFFDirectory *td = &tif->tif_dir;
	tsize_t scanline;

	if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
		if (td->td_photometric == PHOTOMETRIC_YCBCR
		    && !isUpSampled(tif)) {
			uint16 ycbcrsubsampling[2];

			TIFFGetField(tif, TIFFTAG_YCBCRSUBSAMPLING,
				     ycbcrsubsampling + 0,
				     ycbcrsubsampling + 1);

			if (ycbcrsubsampling[0] == 0) {
				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
					     "Invalid YCbCr subsampling");
				return 0;
			}

			scanline = TIFFroundup(td->td_imagewidth,
					       ycbcrsubsampling[0]);
			scanline = TIFFhowmany8(multiply(tif, scanline,
							 td->td_bitspersample,
							 "TIFFScanlineSize"));
			return ((tsize_t)
				summarize(tif, scanline,
					  multiply(tif, 2,
						scanline / ycbcrsubsampling[0],
						"TIFFVStripSize"),
					  "TIFFVStripSize"));
		} else {
			scanline = multiply(tif, td->td_imagewidth,
					    td->td_samplesperpixel,
					    "TIFFScanlineSize");
		}
	} else
		scanline = td->td_imagewidth;
	return ((tsize_t) TIFFhowmany8(multiply(tif, scanline,
						td->td_bitspersample,
						"TIFFScanlineSize")));
}
Пример #7
0
/*
 * Return nonzero if the data is returned up-sampled.
 */
int
TIFFIsUpSampled(TIFF* tif)
{
    return (isUpSampled(tif));
}
Пример #8
0
/*
 * Compute the # bytes in a variable height, row-aligned strip.
 */
tsize_t
TIFFVStripSize(TIFF* tif, uint32 nrows)
{
	TIFFDirectory *td = &tif->tif_dir;
	uint32 stripsize;

	if (nrows == (uint32) -1)
		nrows = td->td_imagelength;
	if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
	    td->td_photometric == PHOTOMETRIC_YCBCR &&
	    !isUpSampled(tif)) {
		/*
		 * Packed YCbCr data contain one Cb+Cr for every
		 * HorizontalSampling*VerticalSampling Y values.
		 * Must also roundup width and height when calculating
		 * since images that are not a multiple of the
		 * horizontal/vertical subsampling area include
		 * YCbCr data for the extended image.
		 */
		uint16 ycbcrsubsampling[2];
		uint32 w, scanline, samplingarea;

		TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
				      ycbcrsubsampling + 0,
				      ycbcrsubsampling + 1);

		samplingarea = ycbcrsubsampling[0]*ycbcrsubsampling[1];
		if (samplingarea == 0) {
			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
				     "Invalid YCbCr subsampling");
			return 0;
		}

		w = TIFFroundup(td->td_imagewidth, ycbcrsubsampling[0]);
		scanline = TIFFhowmany8(multiply(tif, w, td->td_bitspersample,
						 "TIFFVStripSize"));
		nrows = TIFFroundup(nrows, ycbcrsubsampling[1]);
		/* NB: don't need TIFFhowmany here 'cuz everything is rounded */
		scanline = multiply(tif, nrows, scanline, "TIFFVStripSize");
		/* a zero anywhere in here means overflow, must return zero */
		if (scanline > 0) {
			uint32 extra =
			    multiply(tif, 2, scanline / samplingarea,
				     "TIFFVStripSize");
			if (extra > 0)
				stripsize = summarize(tif, scanline, extra,
						      "TIFFVStripSize");
			else
				stripsize = 0;
		} else
			stripsize = 0;
	} else
		stripsize = multiply(tif, nrows, TIFFScanlineSize(tif),
				     "TIFFVStripSize");
	/* Because tsize_t is signed, we might have conversion overflow */
	if (((tsize_t) stripsize) < 0) {
		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Integer overflow in %s", "TIFFVStripSize");
		stripsize = 0;
	}
	return (tsize_t) stripsize;
}