private bool JPEGSetupEncode()
{
const string module = "JPEGSetupEncode";
InitializeLibJPEG(true, false);
Debug.Assert(!m_common.IsDecompressor);
/*
* Initialize all JPEG parameters to default values.
* Note that jpeg_set_defaults needs legal values for
* in_color_space and input_components.
*/
m_compression.In_color_space = J_COLOR_SPACE.JCS_UNKNOWN;
m_compression.Input_components = 1;
if (!TIFFjpeg_set_defaults())
return false;
/* Set per-file parameters */
m_photometric = m_tif.m_dir.td_photometric;
switch (m_photometric)
{
case Photometric.YCBCR:
m_h_sampling = m_tif.m_dir.td_ycbcrsubsampling[0];
m_v_sampling = m_tif.m_dir.td_ycbcrsubsampling[1];
/*
* A ReferenceBlackWhite field *must* be present since the
* default value is inappropriate for YCbCr. Fill in the
* proper value if application didn't set it.
*/
FieldValue[] result = m_tif.GetField(TiffTag.REFERENCEBLACKWHITE);
if (result == null)
{
float[] refbw = new float[6];
int top = 1 << m_tif.m_dir.td_bitspersample;
refbw[0] = 0;
refbw[1] = (float)(top - 1L);
refbw[2] = (float)(top >> 1);
refbw[3] = refbw[1];
refbw[4] = refbw[2];
refbw[5] = refbw[1];
m_tif.SetField(TiffTag.REFERENCEBLACKWHITE, refbw);
}
break;
/* disallowed by Tech Note */
case Photometric.PALETTE:
case Photometric.MASK:
Tiff.ErrorExt(m_tif, m_tif.m_clientdata, module,
"PhotometricInterpretation {0} not allowed for JPEG", m_photometric);
return false;
default:
/* TIFF 6.0 forbids subsampling of all other color spaces */
m_h_sampling = 1;
m_v_sampling = 1;
break;
}
/* Verify miscellaneous parameters */
// This would need work if LibTiff.Net ever supports different
// depths for different components, or if LibJpeg.Net ever supports
// run-time selection of depth. Neither is imminent.
if (m_tif.m_dir.td_bitspersample != JpegConstants.BITS_IN_JSAMPLE)
{
Tiff.ErrorExt(m_tif, m_tif.m_clientdata, module,
"BitsPerSample {0} not allowed for JPEG", m_tif.m_dir.td_bitspersample);
return false;
}
m_compression.Data_precision = m_tif.m_dir.td_bitspersample;
if (m_tif.IsTiled())
{
if ((m_tif.m_dir.td_tilelength % (m_v_sampling * JpegConstants.DCTSIZE)) != 0)
{
Tiff.ErrorExt(m_tif, m_tif.m_clientdata, module,
"JPEG tile height must be multiple of {0}", m_v_sampling * JpegConstants.DCTSIZE);
return false;
}
if ((m_tif.m_dir.td_tilewidth % (m_h_sampling * JpegConstants.DCTSIZE)) != 0)
{
Tiff.ErrorExt(m_tif, m_tif.m_clientdata, module,
"JPEG tile width must be multiple of {0}", m_h_sampling * JpegConstants.DCTSIZE);
return false;
}
}
else
{
if (m_tif.m_dir.td_rowsperstrip < m_tif.m_dir.td_imagelength &&
(m_tif.m_dir.td_rowsperstrip % (m_v_sampling * JpegConstants.DCTSIZE)) != 0)
{
Tiff.ErrorExt(m_tif, m_tif.m_clientdata, module,
"RowsPerStrip must be multiple of {0} for JPEG", m_v_sampling * JpegConstants.DCTSIZE);
return false;
}
}
/* Create a JPEGTables field if appropriate */
if ((m_jpegtablesmode & (JpegTablesMode.QUANT | JpegTablesMode.HUFF)) != 0)
{
bool startsWithZeroes = true;
if (m_jpegtables != null)
{
for (int i = 0; i < 8; i++)
{
if (m_jpegtables[i] != 0)
{
startsWithZeroes = false;
break;
}
}
}
else
{
startsWithZeroes = false;
}
if (m_jpegtables == null || startsWithZeroes)
{
if (!prepare_JPEGTables())
return false;
/* Mark the field present */
/* Can't use TIFFSetField since BEENWRITING is already set! */
m_tif.m_flags |= TiffFlags.DIRTYDIRECT;
m_tif.setFieldBit(FIELD_JPEGTABLES);
}
}
else
{
/* We do not support application-supplied JPEGTables, */
/* so mark the field not present */
m_tif.clearFieldBit(FIELD_JPEGTABLES);
}
/* Direct LibJpeg.Net output to LibTiff.Net's output buffer */
TIFFjpeg_data_dest();
return true;
}