public ReadRGBAImageOriented ( int width, int height, int raster, Orientation orientation ) : bool | ||
width | int | The raster width. |
height | int | The raster height. |
raster | int | The raster (the buffer to place decoded image data to). |
orientation | Orientation | The raster origin position. |
Результат | bool |
private static (ProcessState state, SKImage image) ReadFullImage(T.Tiff tiff, ImageRequest request, bool allowSizeAboveFull) { int width = tiff.GetField(T.TiffTag.IMAGEWIDTH)[0].ToInt(); int height = tiff.GetField(T.TiffTag.IMAGELENGTH)[0].ToInt(); var restag = tiff.GetField(T.TiffTag.RESOLUTIONUNIT); var xrestag = tiff.GetField(T.TiffTag.XRESOLUTION); var yrestag = tiff.GetField(T.TiffTag.YRESOLUTION); var resunit = restag == null ? 2 : restag[0].ToShort(); var xres = xrestag == null ? 96 : xrestag[0].ToDouble(); var yres = yrestag == null ? 96 : yrestag[0].ToDouble(); // pixels per metre if (resunit == 3) { xres = xres / 0.0254; yres = yres / 0.0254; } var isTileable = tiff.IsTiled(); var state = ImageRequestInterpreter.GetInterpretedValues(request, width, height, allowSizeAboveFull); state.HorizontalResolution = Convert.ToUInt16(xres); state.VerticalResolution = Convert.ToUInt16(yres); var raster = new int[width * height]; if (!tiff.ReadRGBAImageOriented(width, height, raster, T.Orientation.TOPLEFT)) { throw new IOException("Unable to decode TIFF file"); } using (var bmp = CreateBitmapFromPixels(raster, width, height)) { var desiredWidth = Math.Max(1, (int)Math.Round(state.RegionWidth * state.ImageScale)); var desiredHeight = Math.Max(1, (int)Math.Round(state.RegionHeight * state.ImageScale)); Log.Debug("Desired size {@DesiredWidth}, {@DesiredHeight}", desiredWidth, desiredHeight); var regionWidth = state.RegionWidth; var regionHeight = state.RegionHeight; var srcRegion = SKRectI.Create(state.StartX, state.StartY, regionWidth, regionHeight); return(state, CopyImageRegion2(bmp, desiredWidth, desiredHeight, srcRegion)); } }
/* 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; }
/// <summary> /// Read the whole image into one big RGBA buffer and then write out /// strips from that. This is using the traditional TIFFReadRGBAImage() /// API that we trust. /// </summary> private bool cvt_whole_image(Tiff inImage, Tiff outImage, int width, int height) { int pixel_count = width * height; /* XXX: Check the integer overflow. */ if (width == 0 || height == 0 || (pixel_count / width) != height) { Tiff.Error(inImage.FileName(), "Malformed input file; can't allocate buffer for raster of {0}x{1} size", width, height); return false; } m_rowsPerStrip = outImage.DefaultStripSize(m_rowsPerStrip); outImage.SetField(TiffTag.ROWSPERSTRIP, m_rowsPerStrip); int[] raster = new int[pixel_count]; /* Read the image in one chunk into an RGBA array */ if (!inImage.ReadRGBAImageOriented(width, height, raster, Orientation.TOPLEFT, false)) return false; /* * Do we want to strip away alpha components? */ byte[] rasterBytes; int rasterByteSize; if (m_noAlpha) { rasterByteSize = pixel_count * 3; rasterBytes = new byte[rasterByteSize]; for (int i = 0, rasterBytesPos = 0; i < pixel_count; i++) { byte[] bytes = BitConverter.GetBytes(raster[i]); rasterBytes[rasterBytesPos++] = bytes[0]; rasterBytes[rasterBytesPos++] = bytes[1]; rasterBytes[rasterBytesPos++] = bytes[2]; } } else { rasterByteSize = pixel_count * 4; rasterBytes = new byte[rasterByteSize]; Buffer.BlockCopy(raster, 0, rasterBytes, 0, rasterByteSize); } /* * Write out the result in strips */ for (int row = 0; row < height; row += m_rowsPerStrip) { int bytes_per_pixel; if (m_noAlpha) bytes_per_pixel = 3; else bytes_per_pixel = 4; int rows_to_write; if (row + m_rowsPerStrip > height) rows_to_write = height - row; else rows_to_write = m_rowsPerStrip; int offset = bytes_per_pixel * row * width; int count = bytes_per_pixel * rows_to_write * width; if (outImage.WriteEncodedStrip(row / m_rowsPerStrip, rasterBytes, offset, count) == -1) return false; } return true; }