private int write_pdf_xobject_icccs_dict() { int written = writeToFile("/N "); string buffer = string.Format(CultureInfo.InvariantCulture, "{0} \n", m_tiff_samplesperpixel); written += writeToFile(buffer); written += writeToFile("/Alternate "); m_pdf_colorspace = (t2p_cs_t)(m_pdf_colorspace ^ t2p_cs_t.T2P_CS_ICCBASED); written += write_pdf_xobject_cs(); m_pdf_colorspace = (t2p_cs_t)(m_pdf_colorspace | t2p_cs_t.T2P_CS_ICCBASED); written += write_pdf_stream_dict(m_tiff_iccprofilelength, 0); return written; }
/* This function sets the input directory to the directory of a given page and determines information about the image. It checks the image characteristics to determine if it is possible to convert the image data into a page of PDF output, setting values of the T2P struct for this page. It determines what color space is used in the output PDF to represent the image. It determines if the image can be converted as raw data without requiring transcoding of the image data. */ private void read_tiff_data(Tiff input) { m_pdf_transcode = t2p_transcode_t.T2P_TRANSCODE_ENCODE; m_pdf_sample = t2p_sample_t.T2P_SAMPLE_NOTHING; m_pdf_switchdecode = m_pdf_colorspace_invert; input.SetDirectory(m_tiff_pages[m_pdf_page].page_directory); FieldValue[] result = input.GetField(TiffTag.IMAGEWIDTH); m_tiff_width = result[0].ToInt(); if (m_tiff_width == 0) { Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, "No support for {0} with zero width", input.FileName()); m_error = true; return; } result = input.GetField(TiffTag.IMAGELENGTH); m_tiff_length = result[0].ToInt(); if (m_tiff_length == 0) { Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, "No support for {0} with zero length", input.FileName()); m_error = true; return; } result = input.GetField(TiffTag.COMPRESSION); if (result == null) { Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, "No support for {0} with no compression tag", input.FileName()); m_error = true; return; } else m_tiff_compression = (Compression)result[0].ToInt(); if (!input.IsCodecConfigured(m_tiff_compression)) { Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, "No support for {0} with compression type {1}: not configured", input.FileName(), m_tiff_compression); m_error = true; return; } result = input.GetFieldDefaulted(TiffTag.BITSPERSAMPLE); m_tiff_bitspersample = result[0].ToShort(); switch (m_tiff_bitspersample) { case 1: case 2: case 4: case 8: break; case 0: Tiff.Warning(Tiff2PdfConstants.TIFF2PDF_MODULE, "Image {0} has 0 bits per sample, assuming 1", input.FileName()); m_tiff_bitspersample = 1; break; default: Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, "No support for {0} with {1} bits per sample", input.FileName(), m_tiff_bitspersample); m_error = true; return; } result = input.GetFieldDefaulted(TiffTag.SAMPLESPERPIXEL); m_tiff_samplesperpixel = result[0].ToShort(); if (m_tiff_samplesperpixel > 4) { Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, "No support for {0} with {1} samples per pixel", input.FileName(), m_tiff_samplesperpixel); m_error = true; return; } if (m_tiff_samplesperpixel == 0) { Tiff.Warning(Tiff2PdfConstants.TIFF2PDF_MODULE, "Image {0} has 0 samples per pixel, assuming 1", input.FileName()); m_tiff_samplesperpixel = 1; } result = input.GetField(TiffTag.SAMPLEFORMAT); if (result != null) { SampleFormat f = (SampleFormat)result[0].ToByte(); switch (f) { case 0: case SampleFormat.UINT: case SampleFormat.VOID: break; default: Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, "No support for {0} with sample format {1}", input.FileName(), f); m_error = true; return; } } result = input.GetFieldDefaulted(TiffTag.FILLORDER); m_tiff_fillorder = (FillOrder)result[0].ToByte(); result = input.GetField(TiffTag.PHOTOMETRIC); if (result == null) { Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, "No support for {0} with no photometric interpretation tag", input.FileName()); m_error = true; return; } else m_tiff_photometric = (Photometric)result[0].ToInt(); short[] r; short[] g; short[] b; short[] a; bool photometric_palette; bool photometric_palette_cmyk; switch (m_tiff_photometric) { case Photometric.MINISWHITE: case Photometric.MINISBLACK: if (m_tiff_bitspersample == 1) { m_pdf_colorspace = t2p_cs_t.T2P_CS_BILEVEL; if (m_tiff_photometric == Photometric.MINISWHITE) m_pdf_switchdecode ^= true; } else { m_pdf_colorspace = t2p_cs_t.T2P_CS_GRAY; if (m_tiff_photometric == Photometric.MINISWHITE) m_pdf_switchdecode ^= true; } break; case Photometric.RGB: case Photometric.PALETTE: photometric_palette = (m_tiff_photometric == Photometric.PALETTE); if (!photometric_palette) { m_pdf_colorspace = t2p_cs_t.T2P_CS_RGB; if (m_tiff_samplesperpixel == 3) break; result = input.GetField(TiffTag.INDEXED); if (result != null) { if (result[0].ToInt() == 1) photometric_palette = true; } } if (!photometric_palette) { if (m_tiff_samplesperpixel > 3) { if (m_tiff_samplesperpixel == 4) { m_pdf_colorspace = t2p_cs_t.T2P_CS_RGB; result = input.GetField(TiffTag.EXTRASAMPLES); if (result != null && result[0].ToInt() == 1) { byte[] xuint16p = result[1].ToByteArray(); if ((ExtraSample)xuint16p[0] == ExtraSample.ASSOCALPHA) { m_pdf_sample = t2p_sample_t.T2P_SAMPLE_RGBAA_TO_RGB; break; } if ((ExtraSample)xuint16p[0] == ExtraSample.UNASSALPHA) { m_pdf_sample = t2p_sample_t.T2P_SAMPLE_RGBA_TO_RGB; break; } Tiff.Warning(Tiff2PdfConstants.TIFF2PDF_MODULE, "RGB image {0} has 4 samples per pixel, assuming RGBA", input.FileName()); break; } m_pdf_colorspace = t2p_cs_t.T2P_CS_CMYK; m_pdf_switchdecode ^= true; Tiff.Warning(Tiff2PdfConstants.TIFF2PDF_MODULE, "RGB image {0} has 4 samples per pixel, assuming inverse CMYK", input.FileName()); break; } else { Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, "No support for RGB image {0} with {1} samples per pixel", input.FileName(), m_tiff_samplesperpixel); m_error = true; break; } } else { Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, "No support for RGB image {0} with {1} samples per pixel", input.FileName(), m_tiff_samplesperpixel); m_error = true; break; } } if (photometric_palette) { if (m_tiff_samplesperpixel != 1) { Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, "No support for palletized image {0} with not one sample per pixel", input.FileName()); m_error = true; return; } m_pdf_colorspace = (t2p_cs_t)(t2p_cs_t.T2P_CS_RGB | t2p_cs_t.T2P_CS_PALETTE); m_pdf_palettesize = 0x0001 << m_tiff_bitspersample; result = input.GetField(TiffTag.COLORMAP); if (result == null) { Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, "Palletized image {0} has no color map", input.FileName()); m_error = true; return; } else { r = result[0].ToShortArray(); g = result[1].ToShortArray(); b = result[2].ToShortArray(); } m_pdf_palette = new byte [m_pdf_palettesize * 3]; for (int i = 0; i < m_pdf_palettesize; i++) { m_pdf_palette[i * 3] = (byte)(r[i] >> 8); m_pdf_palette[i * 3 + 1] = (byte)(g[i] >> 8); m_pdf_palette[i * 3 + 2] = (byte)(b[i] >> 8); } m_pdf_palettesize *= 3; } break; case Photometric.SEPARATED: photometric_palette_cmyk = false; result = input.GetField(TiffTag.INDEXED); if (result != null) { if (result[0].ToInt() == 1) photometric_palette_cmyk = true; } if (!photometric_palette_cmyk) { result = input.GetField(TiffTag.INKSET); if (result != null) { if ((InkSet)result[0].ToByte() != InkSet.CMYK) { Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, "No support for {0} because its inkset is not CMYK", input.FileName()); m_error = true; return; } } if (m_tiff_samplesperpixel == 4) { m_pdf_colorspace = t2p_cs_t.T2P_CS_CMYK; } else { Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, "No support for {0} because it has {1} samples per pixel", input.FileName(), m_tiff_samplesperpixel); m_error = true; return; } } else { if (m_tiff_samplesperpixel != 1) { Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, "No support for palletized CMYK image {0} with not one sample per pixel", input.FileName()); m_error = true; return; } m_pdf_colorspace = (t2p_cs_t)(t2p_cs_t.T2P_CS_CMYK | t2p_cs_t.T2P_CS_PALETTE); m_pdf_palettesize = 0x0001 << m_tiff_bitspersample; result = input.GetField(TiffTag.COLORMAP); if (result == null) { Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, "Palletized image {0} has no color map", input.FileName()); m_error = true; return; } else { r = result[0].ToShortArray(); g = result[1].ToShortArray(); b = result[2].ToShortArray(); a = result[3].ToShortArray(); } m_pdf_palette = new byte [m_pdf_palettesize * 4]; for (int i = 0; i < m_pdf_palettesize; i++) { m_pdf_palette[i * 4] = (byte)(r[i] >> 8); m_pdf_palette[i * 4 + 1] = (byte)(g[i] >> 8); m_pdf_palette[i * 4 + 2] = (byte)(b[i] >> 8); m_pdf_palette[i * 4 + 3] = (byte)(a[i] >> 8); } m_pdf_palettesize *= 4; } break; case Photometric.YCBCR: m_pdf_colorspace = t2p_cs_t.T2P_CS_RGB; if (m_tiff_samplesperpixel == 1) { m_pdf_colorspace = t2p_cs_t.T2P_CS_GRAY; m_tiff_photometric = Photometric.MINISBLACK; break; } m_pdf_sample = t2p_sample_t.T2P_SAMPLE_YCBCR_TO_RGB; if (m_pdf_defaultcompression == t2p_compress_t.T2P_COMPRESS_JPEG) m_pdf_sample = t2p_sample_t.T2P_SAMPLE_NOTHING; break; case Photometric.CIELAB: m_pdf_labrange[0] = -127; m_pdf_labrange[1] = 127; m_pdf_labrange[2] = -127; m_pdf_labrange[3] = 127; m_pdf_sample = t2p_sample_t.T2P_SAMPLE_LAB_SIGNED_TO_UNSIGNED; m_pdf_colorspace = t2p_cs_t.T2P_CS_LAB; break; case Photometric.ICCLAB: m_pdf_labrange[0] = 0; m_pdf_labrange[1] = 255; m_pdf_labrange[2] = 0; m_pdf_labrange[3] = 255; m_pdf_colorspace = t2p_cs_t.T2P_CS_LAB; break; case Photometric.ITULAB: m_pdf_labrange[0] = -85; m_pdf_labrange[1] = 85; m_pdf_labrange[2] = -75; m_pdf_labrange[3] = 124; m_pdf_sample = t2p_sample_t.T2P_SAMPLE_LAB_SIGNED_TO_UNSIGNED; m_pdf_colorspace = t2p_cs_t.T2P_CS_LAB; break; case Photometric.LOGL: case Photometric.LOGLUV: Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, "No support for {0} with photometric interpretation LogL/LogLuv", input.FileName()); m_error = true; return; default: Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, "No support for {0} with photometric interpretation {1}", input.FileName(), m_tiff_photometric); m_error = true; return; } result = input.GetField(TiffTag.PLANARCONFIG); if (result != null) { m_tiff_planar = (PlanarConfig)result[0].ToShort(); switch (m_tiff_planar) { case 0: Tiff.Warning(Tiff2PdfConstants.TIFF2PDF_MODULE, "Image {0} has planar configuration 0, assuming 1", input.FileName()); m_tiff_planar = PlanarConfig.CONTIG; break; case PlanarConfig.CONTIG: break; case PlanarConfig.SEPARATE: m_pdf_sample = t2p_sample_t.T2P_SAMPLE_PLANAR_SEPARATE_TO_CONTIG; if (m_tiff_bitspersample != 8) { Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, "No support for {0} with separated planar configuration and {1} bits per sample", input.FileName(), m_tiff_bitspersample); m_error = true; return; } break; default: Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, "No support for {0} with planar configuration {1}", input.FileName(), m_tiff_planar); m_error = true; return; } } result = input.GetFieldDefaulted(TiffTag.ORIENTATION); m_tiff_orientation = (Orientation)result[0].ToByte(); if (m_tiff_orientation > Orientation.LEFTBOT) { Tiff.Warning(Tiff2PdfConstants.TIFF2PDF_MODULE, "Image {0} has orientation {1}, assuming 0", input.FileName(), m_tiff_orientation); m_tiff_orientation = 0; } result = input.GetField(TiffTag.XRESOLUTION); if (result == null) m_tiff_xres = 0.0f; else m_tiff_xres = result[0].ToFloat(); result = input.GetField(TiffTag.YRESOLUTION); if (result == null) m_tiff_yres = 0.0f; else m_tiff_yres = result[0].ToFloat(); result = input.GetFieldDefaulted(TiffTag.RESOLUTIONUNIT); m_tiff_resunit = (ResUnit)result[0].ToByte(); if (m_tiff_resunit == ResUnit.CENTIMETER) { m_tiff_xres *= 2.54F; m_tiff_yres *= 2.54F; } else if (m_tiff_resunit != ResUnit.INCH && m_pdf_centimeters) { m_tiff_xres *= 2.54F; m_tiff_yres *= 2.54F; } compose_pdf_page(); m_pdf_transcode = t2p_transcode_t.T2P_TRANSCODE_ENCODE; if (!m_pdf_nopassthrough) { if (m_tiff_compression == Compression.CCITTFAX4) { if (input.IsTiled() || (input.NumberOfStrips() == 1)) { m_pdf_transcode = t2p_transcode_t.T2P_TRANSCODE_RAW; m_pdf_compression = t2p_compress_t.T2P_COMPRESS_G4; } } if (m_tiff_compression == Compression.ADOBE_DEFLATE || m_tiff_compression == Compression.DEFLATE) { if (input.IsTiled() || (input.NumberOfStrips() == 1)) { m_pdf_transcode = t2p_transcode_t.T2P_TRANSCODE_RAW; m_pdf_compression = t2p_compress_t.T2P_COMPRESS_ZIP; } } if (m_tiff_compression == Compression.JPEG) { m_pdf_transcode = t2p_transcode_t.T2P_TRANSCODE_RAW; m_pdf_compression = t2p_compress_t.T2P_COMPRESS_JPEG; } } if (m_pdf_transcode != t2p_transcode_t.T2P_TRANSCODE_RAW) m_pdf_compression = m_pdf_defaultcompression; if (m_pdf_defaultcompression == t2p_compress_t.T2P_COMPRESS_JPEG) { if ((m_pdf_colorspace & t2p_cs_t.T2P_CS_PALETTE) != 0) { m_pdf_sample = (t2p_sample_t)(m_pdf_sample | t2p_sample_t.T2P_SAMPLE_REALIZE_PALETTE); m_pdf_colorspace = (t2p_cs_t)(m_pdf_colorspace ^ t2p_cs_t.T2P_CS_PALETTE); m_tiff_pages[m_pdf_page].page_extra--; } } if (m_tiff_compression == Compression.JPEG) { if (m_tiff_planar == PlanarConfig.SEPARATE) { Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, "No support for {0} with JPEG compression and separated planar configuration", input.FileName()); m_error = true; return; } } if ((m_pdf_sample & t2p_sample_t.T2P_SAMPLE_REALIZE_PALETTE) != 0) { if ((m_pdf_colorspace & t2p_cs_t.T2P_CS_CMYK) != 0) { m_tiff_samplesperpixel = 4; m_tiff_photometric = Photometric.SEPARATED; } else { m_tiff_samplesperpixel = 3; m_tiff_photometric = Photometric.RGB; } } result = input.GetField(TiffTag.TRANSFERFUNCTION); if (result != null) { m_tiff_transferfunction[0] = result[0].GetBytes(); m_tiff_transferfunction[1] = result[1].GetBytes(); m_tiff_transferfunction[2] = result[2].GetBytes(); if (m_tiff_transferfunction[1] != m_tiff_transferfunction[0]) m_tiff_transferfunctioncount = 3; else m_tiff_transferfunctioncount = 1; } else { m_tiff_transferfunctioncount = 0; } result = input.GetField(TiffTag.WHITEPOINT); if (result != null) { float[] xfloatp = result[0].ToFloatArray(); m_tiff_whitechromaticities[0] = xfloatp[0]; m_tiff_whitechromaticities[1] = xfloatp[1]; if ((m_pdf_colorspace & t2p_cs_t.T2P_CS_GRAY) != 0) m_pdf_colorspace = (t2p_cs_t)(m_pdf_colorspace | t2p_cs_t.T2P_CS_CALGRAY); if ((m_pdf_colorspace & t2p_cs_t.T2P_CS_RGB) != 0) m_pdf_colorspace = (t2p_cs_t)(m_pdf_colorspace | t2p_cs_t.T2P_CS_CALRGB); } result = input.GetField(TiffTag.PRIMARYCHROMATICITIES); if (result != null) { float[] xfloatp = result[0].ToFloatArray(); m_tiff_primarychromaticities[0] = xfloatp[0]; m_tiff_primarychromaticities[1] = xfloatp[1]; m_tiff_primarychromaticities[2] = xfloatp[2]; m_tiff_primarychromaticities[3] = xfloatp[3]; m_tiff_primarychromaticities[4] = xfloatp[4]; m_tiff_primarychromaticities[5] = xfloatp[5]; if ((m_pdf_colorspace & t2p_cs_t.T2P_CS_RGB) != 0) m_pdf_colorspace = (t2p_cs_t)(m_pdf_colorspace | t2p_cs_t.T2P_CS_CALRGB); } if ((m_pdf_colorspace & t2p_cs_t.T2P_CS_LAB) != 0) { result = input.GetField(TiffTag.WHITEPOINT); if (result != null) { float[] xfloatp = result[0].ToFloatArray(); m_tiff_whitechromaticities[0] = xfloatp[0]; m_tiff_whitechromaticities[1] = xfloatp[1]; } else { m_tiff_whitechromaticities[0] = 0.3457F; /* 0.3127F; */ m_tiff_whitechromaticities[1] = 0.3585F; /* 0.3290F; */ } } result = input.GetField(TiffTag.ICCPROFILE); if (result != null) { m_tiff_iccprofilelength = result[0].ToInt(); m_tiff_iccprofile = result[1].ToByteArray(); m_pdf_colorspace = (t2p_cs_t)(m_pdf_colorspace | t2p_cs_t.T2P_CS_ICCBASED); } else { m_tiff_iccprofilelength = 0; m_tiff_iccprofile = null; } if (m_tiff_bitspersample == 1 && m_tiff_samplesperpixel == 1) m_pdf_compression = t2p_compress_t.T2P_COMPRESS_G4; }
/* * This function writes a PDF Image XObject Colorspace name to output. */ private int write_pdf_xobject_cs() { if ((m_pdf_colorspace & t2p_cs_t.T2P_CS_ICCBASED) != 0) return write_pdf_xobject_icccs(); int written = 0; string buffer = null; if ((m_pdf_colorspace & t2p_cs_t.T2P_CS_PALETTE) != 0) { written += writeToFile("[ /Indexed "); m_pdf_colorspace = (t2p_cs_t)(m_pdf_colorspace ^ t2p_cs_t.T2P_CS_PALETTE); written += write_pdf_xobject_cs(); m_pdf_colorspace = (t2p_cs_t)(m_pdf_colorspace | t2p_cs_t.T2P_CS_PALETTE); buffer = string.Format(CultureInfo.InvariantCulture, "{0}", (0x0001 << m_tiff_bitspersample) - 1); written += writeToFile(buffer); written += writeToFile(" "); buffer = string.Format(CultureInfo.InvariantCulture, "{0}", m_pdf_palettecs); written += writeToFile(buffer); written += writeToFile(" 0 R ]\n"); return written; } if ((m_pdf_colorspace & t2p_cs_t.T2P_CS_BILEVEL) != 0) written += writeToFile("/DeviceGray \n"); if ((m_pdf_colorspace & t2p_cs_t.T2P_CS_GRAY) != 0) { if ((m_pdf_colorspace & t2p_cs_t.T2P_CS_CALGRAY) != 0) written += write_pdf_xobject_calcs(); else written += writeToFile("/DeviceGray \n"); } if ((m_pdf_colorspace & t2p_cs_t.T2P_CS_RGB) != 0) { if ((m_pdf_colorspace & t2p_cs_t.T2P_CS_CALRGB) != 0) written += write_pdf_xobject_calcs(); else written += writeToFile("/DeviceRGB \n"); } if ((m_pdf_colorspace & t2p_cs_t.T2P_CS_CMYK) != 0) written += writeToFile("/DeviceCMYK \n"); if ((m_pdf_colorspace & t2p_cs_t.T2P_CS_LAB) != 0) { written += writeToFile("[/Lab << \n"); written += writeToFile("/WhitePoint "); float X_W = m_tiff_whitechromaticities[0]; float Y_W = m_tiff_whitechromaticities[1]; float Z_W = 1.0F - (X_W + Y_W); X_W /= Y_W; Z_W /= Y_W; Y_W = 1.0F; buffer = string.Format(CultureInfo.InvariantCulture, "[{0:F4} {1:F4} {2:F4}] \n", X_W, Y_W, Z_W); written += writeToFile(buffer); written += writeToFile("/BlackPoint "); X_W = 0.3457F; /* 0.3127F; */ /* D50, commented D65 */ Y_W = 0.3585F; /* 0.3290F; */ Z_W = 1.0F - (X_W + Y_W); X_W /= Y_W; Z_W /= Y_W; Y_W = 1.0F; buffer = string.Format(CultureInfo.InvariantCulture, "[{0:F4} {1:F4} {2:F4}] \n", X_W, Y_W, Z_W); written += writeToFile(buffer); written += writeToFile("/Range "); buffer = string.Format(CultureInfo.InvariantCulture, "[{0} {1} {2} {3}] \n", m_pdf_labrange[0], m_pdf_labrange[1], m_pdf_labrange[2], m_pdf_labrange[3]); written += writeToFile(buffer); written += writeToFile(">>] \n"); } return written; }