private bool JPEGEncodeRaw(byte[] buffer, int offset, int count, short plane)
{
// data is expected to be supplied in multiples of a clumpline
// a clumpline is equivalent to v_sampling desubsampled scanlines
// TODO: the following calculation of bytesperclumpline, should substitute
// calculation of bytesperline, except that it is per v_sampling lines
int bytesperclumpline = (((m_compression.Image_width + m_h_sampling - 1) / m_h_sampling) *
(m_h_sampling * m_v_sampling + 2) * m_compression.Data_precision + 7) / 8;
int nrows = (count / bytesperclumpline) * m_v_sampling;
if ((count % bytesperclumpline) != 0)
Tiff.WarningExt(m_tif, m_tif.m_clientdata, m_tif.m_name, "fractional scanline discarded");
// Cb,Cr both have sampling factors 1, so this is correct
int clumps_per_line = m_compression.Component_info[1].Downsampled_width;
while (nrows > 0)
{
// Fastest way to separate the data is to make one pass over the scanline for
// each row of each component.
int clumpoffset = 0; // first sample in clump
for (int ci = 0; ci < m_compression.Num_components; ci++)
{
jpeg_component_info compptr = m_compression.Component_info[ci];
int hsamp = compptr.H_samp_factor;
int vsamp = compptr.V_samp_factor;
int padding = compptr.Width_in_blocks * JpegConstants.DCTSIZE - clumps_per_line * hsamp;
for (int ypos = 0; ypos < vsamp; ypos++)
{
int inptr = offset + clumpoffset;
byte[] outbuf = m_ds_buffer[ci][m_scancount * vsamp + ypos];
int outptr = 0;
if (hsamp == 1)
{
// fast path for at least Cb and Cr
for (int nclump = clumps_per_line; nclump-- > 0; )
{
outbuf[outptr] = buffer[inptr];
outptr++;
inptr += m_samplesperclump;
}
}
else
{
// general case
for (int nclump = clumps_per_line; nclump-- > 0; )
{
for (int xpos = 0; xpos < hsamp; xpos++)
{
outbuf[outptr] = buffer[inptr + xpos];
outptr++;
}
inptr += m_samplesperclump;
}
}
// pad each scanline as needed
for (int xpos = 0; xpos < padding; xpos++)
{
outbuf[outptr] = outbuf[outptr - 1];
outptr++;
}
clumpoffset += hsamp;
}
}
m_scancount++;
if (m_scancount >= JpegConstants.DCTSIZE)
{
int n = m_compression.Max_v_samp_factor * JpegConstants.DCTSIZE;
if (TIFFjpeg_write_raw_data(m_ds_buffer, n) != n)
return false;
m_scancount = 0;
}
m_tif.m_row += m_v_sampling;
offset += m_bytesperline;
nrows -= m_v_sampling;
}
return true;
}