/*
This function reads the raster image data from the input TIFF for an image and writes
the data to the output PDF XObject image dictionary stream. It returns the amount written
or zero on error.
*/
private int readwrite_pdf_image(Tiff input)
{
byte[] buffer = null;
int bufferoffset = 0;
int stripcount = 0;
int max_striplength = 0;
FieldValue[] result = null;
if (m_pdf_transcode == t2p_transcode_t.T2P_TRANSCODE_RAW)
{
if (m_pdf_compression == t2p_compress_t.T2P_COMPRESS_G4)
{
buffer = new byte [m_tiff_datasize];
input.ReadRawStrip(0, buffer, 0, m_tiff_datasize);
if (m_tiff_fillorder == FillOrder.LSB2MSB)
{
/*
* make sure is lsb-to-msb
* bit-endianness fill order
*/
Tiff.ReverseBits(buffer, m_tiff_datasize);
}
writeToFile(buffer, m_tiff_datasize);
return m_tiff_datasize;
}
if (m_pdf_compression == t2p_compress_t.T2P_COMPRESS_ZIP)
{
buffer = new byte [m_tiff_datasize];
input.ReadRawStrip(0, buffer, 0, m_tiff_datasize);
if (m_tiff_fillorder == FillOrder.LSB2MSB)
Tiff.ReverseBits(buffer, m_tiff_datasize);
writeToFile(buffer, m_tiff_datasize);
return m_tiff_datasize;
}
if (m_tiff_compression == Compression.JPEG)
{
buffer = new byte [m_tiff_datasize];
result = input.GetField(TiffTag.JPEGTABLES);
if (result != null)
{
int count = result[0].ToInt();
byte[] jpt = result[1].ToByteArray();
if (count > 4)
{
Buffer.BlockCopy(jpt, 0, buffer, 0, count);
bufferoffset += count - 2;
}
}
stripcount = input.NumberOfStrips();
result = input.GetField(TiffTag.STRIPBYTECOUNTS);
int[] sbc = result[0].ToIntArray();
for (int i = 0; i < stripcount; i++)
{
if (sbc[i] > max_striplength)
max_striplength = sbc[i];
}
byte[] stripbuffer = new byte [max_striplength];
for (int i = 0; i < stripcount; i++)
{
int striplength = input.ReadRawStrip(i, stripbuffer, 0, -1);
if (!process_jpeg_strip(stripbuffer, striplength, buffer, ref bufferoffset, stripcount, i, m_tiff_length))
{
Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
"Can't process JPEG data in input file {0}", input.FileName());
m_error = true;
return 0;
}
}
buffer[bufferoffset++] = 0xff;
buffer[bufferoffset++] = 0xd9;
writeToFile(buffer, bufferoffset);
return bufferoffset;
}
}
int stripsize = 0;
if (m_pdf_sample == t2p_sample_t.T2P_SAMPLE_NOTHING)
{
buffer = new byte [m_tiff_datasize];
stripsize = input.StripSize();
stripcount = input.NumberOfStrips();
for (int i = 0; i < stripcount; i++)
{
int read = input.ReadEncodedStrip(i, buffer, bufferoffset, stripsize);
if (read == -1)
{
Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
"Error on decoding strip {0} of {1}", i, input.FileName());
m_error = true;
return 0;
}
bufferoffset += read;
}
}
else
{
byte[] samplebuffer = null;
bool dataready = false;
if ((m_pdf_sample & t2p_sample_t.T2P_SAMPLE_PLANAR_SEPARATE_TO_CONTIG) != 0)
{
int sepstripsize = input.StripSize();
int sepstripcount = input.NumberOfStrips();
stripsize = sepstripsize * m_tiff_samplesperpixel;
stripcount = sepstripcount / m_tiff_samplesperpixel;
buffer = new byte [m_tiff_datasize];
samplebuffer = new byte [stripsize];
for (int i = 0; i < stripcount; i++)
{
int samplebufferoffset = 0;
for (int j = 0; j < m_tiff_samplesperpixel; j++)
{
int read = input.ReadEncodedStrip(i + j * stripcount, samplebuffer, samplebufferoffset, sepstripsize);
if (read == -1)
{
Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
"Error on decoding strip {0} of {1}",
i + j * stripcount, input.FileName());
m_error = true;
return 0;
}
samplebufferoffset += read;
}
sample_planar_separate_to_contig(buffer, bufferoffset, samplebuffer, samplebufferoffset);
bufferoffset += samplebufferoffset;
}
dataready = true;
}
if (!dataready)
{
buffer = new byte [m_tiff_datasize];
stripsize = input.StripSize();
stripcount = input.NumberOfStrips();
for (int i = 0; i < stripcount; i++)
{
int read = input.ReadEncodedStrip(i, buffer, bufferoffset, stripsize);
if (read == -1)
{
Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
"Error on decoding strip {0} of {1}", i, input.FileName());
m_error = true;
return 0;
}
bufferoffset += read;
}
if ((m_pdf_sample & t2p_sample_t.T2P_SAMPLE_REALIZE_PALETTE) != 0)
{
samplebuffer = Tiff.Realloc(buffer, m_tiff_datasize * m_tiff_samplesperpixel);
buffer = samplebuffer;
m_tiff_datasize *= m_tiff_samplesperpixel;
sample_realize_palette(buffer);
}
if ((m_pdf_sample & t2p_sample_t.T2P_SAMPLE_RGBA_TO_RGB) != 0)
m_tiff_datasize = sample_rgba_to_rgb(buffer, m_tiff_width * m_tiff_length);
if ((m_pdf_sample & t2p_sample_t.T2P_SAMPLE_RGBAA_TO_RGB) != 0)
m_tiff_datasize = sample_rgbaa_to_rgb(buffer, m_tiff_width * m_tiff_length);
if ((m_pdf_sample & t2p_sample_t.T2P_SAMPLE_YCBCR_TO_RGB) != 0)
{
samplebuffer = Tiff.Realloc(buffer, m_tiff_width * m_tiff_length * 4);
buffer = samplebuffer;
int[] buffer32 = Tiff.ByteArrayToInts(buffer, 0, m_tiff_width * m_tiff_length * 4);
if (!input.ReadRGBAImageOriented(m_tiff_width, m_tiff_length, buffer32, Orientation.TOPLEFT, false))
{
Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
"Can't use ReadRGBAImageOriented to extract RGB image from {0}",
input.FileName());
m_error = true;
return 0;
}
Tiff.IntsToByteArray(buffer32, 0, m_tiff_width * m_tiff_length, buffer, 0);
m_tiff_datasize = sample_abgr_to_rgb(buffer, m_tiff_width * m_tiff_length);
}
if ((m_pdf_sample & t2p_sample_t.T2P_SAMPLE_LAB_SIGNED_TO_UNSIGNED) != 0)
m_tiff_datasize = sample_lab_signed_to_unsigned(buffer, m_tiff_width * m_tiff_length);
}
}
disable(m_output);
m_output.SetField(TiffTag.PHOTOMETRIC, m_tiff_photometric);
m_output.SetField(TiffTag.BITSPERSAMPLE, m_tiff_bitspersample);
m_output.SetField(TiffTag.SAMPLESPERPIXEL, m_tiff_samplesperpixel);
m_output.SetField(TiffTag.IMAGEWIDTH, m_tiff_width);
m_output.SetField(TiffTag.IMAGELENGTH, m_tiff_length);
m_output.SetField(TiffTag.ROWSPERSTRIP, m_tiff_length);
m_output.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);
m_output.SetField(TiffTag.FILLORDER, FillOrder.MSB2LSB);
switch (m_pdf_compression)
{
case t2p_compress_t.T2P_COMPRESS_NONE:
m_output.SetField(TiffTag.COMPRESSION, Compression.NONE);
break;
case t2p_compress_t.T2P_COMPRESS_G4:
m_output.SetField(TiffTag.COMPRESSION, Compression.CCITTFAX4);
break;
case t2p_compress_t.T2P_COMPRESS_JPEG:
if (m_tiff_photometric == Photometric.YCBCR)
{
result = input.GetField(TiffTag.YCBCRSUBSAMPLING);
if (result != null)
{
short hor = result[0].ToShort();
short ver = result[1].ToShort();
if (hor != 0 && ver != 0)
m_output.SetField(TiffTag.YCBCRSUBSAMPLING, hor, ver);
}
result = input.GetField(TiffTag.REFERENCEBLACKWHITE);
if (result != null)
{
float[] xfloatp = result[0].ToFloatArray();
m_output.SetField(TiffTag.REFERENCEBLACKWHITE, xfloatp);
}
}
if (!m_output.SetField(TiffTag.COMPRESSION, Compression.JPEG))
{
Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
"Unable to use JPEG compression for input {0} and output {1}",
input.FileName(), m_output.FileName());
m_error = true;
return 0;
}
m_output.SetField(TiffTag.JPEGTABLESMODE, 0);
if ((m_pdf_colorspace & (t2p_cs_t.T2P_CS_RGB | t2p_cs_t.T2P_CS_LAB)) != 0)
{
m_output.SetField(TiffTag.PHOTOMETRIC, Photometric.YCBCR);
if (m_tiff_photometric != Photometric.YCBCR)
m_output.SetField(TiffTag.JPEGCOLORMODE, JpegColorMode.RGB);
else
m_output.SetField(TiffTag.JPEGCOLORMODE, JpegColorMode.RAW);
}
if (m_pdf_defaultcompressionquality != 0)
m_output.SetField(TiffTag.JPEGQUALITY, m_pdf_defaultcompressionquality);
break;
case t2p_compress_t.T2P_COMPRESS_ZIP:
m_output.SetField(TiffTag.COMPRESSION, Compression.DEFLATE);
if (m_pdf_defaultcompressionquality % 100 != 0)
m_output.SetField(TiffTag.PREDICTOR, m_pdf_defaultcompressionquality % 100);
if (m_pdf_defaultcompressionquality / 100 != 0)
m_output.SetField(TiffTag.ZIPQUALITY, (m_pdf_defaultcompressionquality / 100));
break;
default:
break;
}
enable(m_output);
m_outputwritten = 0;
if (m_pdf_compression == t2p_compress_t.T2P_COMPRESS_JPEG && m_tiff_photometric == Photometric.YCBCR)
bufferoffset = m_output.WriteEncodedStrip(0, buffer, stripsize * stripcount);
else
bufferoffset = m_output.WriteEncodedStrip(0, buffer, m_tiff_datasize);
buffer = null;
if (bufferoffset == -1)
{
Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
"Error writing encoded strip to output PDF {0}", m_output.FileName());
m_error = true;
return 0;
}
return m_outputwritten;
}