SetField() public method

Sets the value(s) of a tag in a TIFF file/stream open for writing.

SetField sets the value of a tag or pseudo-tag in the current directory associated with the open TIFF file/stream. To set the value of a field the file/stream must have been previously opened for writing with Open(string, string) or ClientOpen(string, string, object, BitMiracle.LibTiff.Classic.TiffStream); pseudo-tags can be set whether the file was opened for reading or writing. The tag is identified by tag. The type and number of values in value is dependent on the tag being set. You may want to consult "Well-known tags and their value(s) data types" to become familiar with exact data types and calling conventions required for each tag supported by the library.

A pseudo-tag is a parameter that is used to control the operation of the library but whose value is not read or written to the underlying file.

The field will be written to the file when/if the directory structure is updated.

public SetField ( TiffTag tag ) : bool
tag TiffTag The tag.
return bool
Esempio n. 1
0
    public TiffGrid(string filename, string NewFileName)
    {
      ValuesToWrite = new Dictionary<int, Dictionary<int, double>>();

      tiff_org = BitMiracle.LibTiff.Classic.Tiff.Open(Path.GetFullPath(filename), "r");

      tiff = BitMiracle.LibTiff.Classic.Tiff.Open(Path.GetFullPath(NewFileName), "w");
      foreach (TiffTag enu in Enum.GetValues(typeof(TiffTag)))
      {
        var val = tiff_org.GetField(enu);
        if (val != null & enu != TiffTag.EXTRASAMPLES)
          tiff.SetField(enu, val[0]);
      }

      for (int i = 0; i < tiff_org.GetTagListCount(); i++)
      {
        int k = tiff_org.GetTagListEntry(i);
        var ff = tiff_org.FindFieldInfo((TiffTag)k, TiffType.ANY);
        tiff.MergeFieldInfo(new TiffFieldInfo[] { ff }, 1);
        var val = tiff_org.GetField((TiffTag)tiff_org.GetTagListEntry(i));
        tiff.SetField((TiffTag)k, val[0], val[1]);
      }

      var val2 = tiff_org.GetField((TiffTag)33922)[1].ToDoubleArray();
      XOrigin = val2[3];
      YOrigin = val2[4]; //Upper basegrid assumes Lower
      val2 = tiff_org.GetField((TiffTag)33550)[1].ToDoubleArray();
      GridSize = val2[0];
      GridSize = val2[1];
      NumberOfColumns = tiff_org.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
      NumberOfRows = tiff_org.GetField(TiffTag.IMAGELENGTH)[0].ToInt();

      //Shift YOrigin to lower left
      YOrigin -= GridSize * NumberOfRows;
      scanline = new byte[tiff_org.ScanlineSize()];
      bits = scanline.Count() / NumberOfColumns;
      ScanLineCache = new Dictionary<int, byte[]>();




    }
Esempio n. 2
0
        public bool Copy(Tiff inImage, Tiff outImage)
        {
            int width = 0;
            FieldValue[] result = inImage.GetField(TiffTag.IMAGEWIDTH);
            if (result != null)
            {
                width = result[0].ToInt();
                outImage.SetField(TiffTag.IMAGEWIDTH, width);
            }

            int length = 0;
            result = inImage.GetField(TiffTag.IMAGELENGTH);
            if (result != null)
            {
                length = result[0].ToInt();
                outImage.SetField(TiffTag.IMAGELENGTH, length);
            }

            short bitspersample = 1;
            result = inImage.GetField(TiffTag.BITSPERSAMPLE);
            if (result != null)
            {
                bitspersample = result[0].ToShort();
                outImage.SetField(TiffTag.BITSPERSAMPLE, bitspersample);
            }

            short samplesperpixel = 1;
            result = inImage.GetField(TiffTag.SAMPLESPERPIXEL);
            if (result != null)
            {
                samplesperpixel = result[0].ToShort();
                outImage.SetField(TiffTag.SAMPLESPERPIXEL, samplesperpixel);
            }

            if (m_compression != (Compression)(-1))
                outImage.SetField(TiffTag.COMPRESSION, m_compression);
            else
            {
                result = inImage.GetField(TiffTag.COMPRESSION);
                if (result != null)
                {
                    m_compression = (Compression)result[0].ToInt();
                    outImage.SetField(TiffTag.COMPRESSION, m_compression);
                }
            }

            result = inImage.GetFieldDefaulted(TiffTag.COMPRESSION);
            Compression input_compression = (Compression)result[0].ToInt();

            result = inImage.GetFieldDefaulted(TiffTag.PHOTOMETRIC);
            Photometric input_photometric = (Photometric)result[0].ToShort();
    
            if (input_compression == Compression.JPEG)
            {
                /* Force conversion to RGB */
                inImage.SetField(TiffTag.JPEGCOLORMODE, JpegColorMode.RGB);
            }
            else if (input_photometric == Photometric.YCBCR)
            {
                /* Otherwise, can't handle subsampled input */
                result = inImage.GetFieldDefaulted(TiffTag.YCBCRSUBSAMPLING);
                short subsamplinghor = result[0].ToShort();
                short subsamplingver = result[1].ToShort();

                if (subsamplinghor != 1 || subsamplingver != 1)
                {
                    Console.Error.WriteLine("tiffcp: {0}: Can't copy/convert subsampled image.", inImage.FileName());
                    return false;
                }
            }

            if (m_compression == Compression.JPEG)
            {
                if (input_photometric == Photometric.RGB && m_jpegcolormode == JpegColorMode.RGB)
                    outImage.SetField(TiffTag.PHOTOMETRIC, Photometric.YCBCR);
                else
                    outImage.SetField(TiffTag.PHOTOMETRIC, input_photometric);
            }
            else if (m_compression == Compression.SGILOG || m_compression == Compression.SGILOG24)
            {
                outImage.SetField(TiffTag.PHOTOMETRIC, samplesperpixel == 1 ? Photometric.LOGL : Photometric.LOGLUV);
            }
            else
            {
                if (input_compression != Compression.JPEG)
                    copyTag(inImage, outImage, TiffTag.PHOTOMETRIC, 1, TiffType.SHORT);
            }

            if (m_fillorder != 0)
                outImage.SetField(TiffTag.FILLORDER, m_fillorder);
            else
                copyTag(inImage, outImage, TiffTag.FILLORDER, 1, TiffType.SHORT);

            /*
             * Will copy `Orientation' tag from input image
             */
            result = inImage.GetFieldDefaulted(TiffTag.ORIENTATION);
            m_orientation = (Orientation)result[0].ToByte();
            switch (m_orientation)
            {
                case Orientation.BOTRIGHT:
                case Orientation.RIGHTBOT:
                    Tiff.Warning(inImage.FileName(), "using bottom-left orientation");
                    m_orientation = Orientation.BOTLEFT;
                    break;

                case Orientation.LEFTBOT:
                case Orientation.BOTLEFT:
                    break;

                case Orientation.TOPRIGHT:
                case Orientation.RIGHTTOP:
                default:
                    Tiff.Warning(inImage.FileName(), "using top-left orientation");
                    m_orientation = Orientation.TOPLEFT;
                    break;

                case Orientation.LEFTTOP:
                case Orientation.TOPLEFT:
                    break;
            }

            outImage.SetField(TiffTag.ORIENTATION, m_orientation);

            /*
             * Choose tiles/strip for the output image according to
             * the command line arguments (-tiles, -strips) and the
             * structure of the input image.
             */
            if (m_outtiled == -1)
            {
                if (inImage.IsTiled())
                    m_outtiled = 1;
                else
                    m_outtiled = 0;
            }

            if (m_outtiled != 0)
            {
                /*
                 * Setup output file's tile width&height.  If either
                 * is not specified, use either the value from the
                 * input image or, if nothing is defined, use the
                 * library default.
                 */
                if (m_tilewidth == -1)
                {
                    result = inImage.GetFieldDefaulted(TiffTag.TILEWIDTH);
                    if (result != null)
                        m_tilewidth = result[0].ToInt();
                }

                if (m_tilelength == -1)
                {
                    result = inImage.GetFieldDefaulted(TiffTag.TILELENGTH);
                    if (result != null)
                        m_tilelength = result[0].ToInt();
                }

                outImage.DefaultTileSize(ref m_tilewidth, ref m_tilelength);
                outImage.SetField(TiffTag.TILEWIDTH, m_tilewidth);
                outImage.SetField(TiffTag.TILELENGTH, m_tilelength);
            }
            else
            {
                /*
                 * RowsPerStrip is left unspecified: use either the
                 * value from the input image or, if nothing is defined,
                 * use the library default.
                 */
                if (m_rowsperstrip == 0)
                {
                    result = inImage.GetField(TiffTag.ROWSPERSTRIP);
                    if (result == null)
                        m_rowsperstrip = outImage.DefaultStripSize(m_rowsperstrip);
                    else
                        m_rowsperstrip = result[0].ToInt();

                    if (m_rowsperstrip > length && m_rowsperstrip != -1)
                        m_rowsperstrip = length;
                }
                else if (m_rowsperstrip == -1)
                    m_rowsperstrip = length;

                outImage.SetField(TiffTag.ROWSPERSTRIP, m_rowsperstrip);
            }

            if (m_config != PlanarConfig.UNKNOWN)
                outImage.SetField(TiffTag.PLANARCONFIG, m_config);
            else
            {
                result = inImage.GetField(TiffTag.PLANARCONFIG);
                if (result != null)
                {
                    m_config = (PlanarConfig)result[0].ToShort();
                    outImage.SetField(TiffTag.PLANARCONFIG, m_config);
                }
            }

            if (samplesperpixel <= 4)
                copyTag(inImage, outImage, TiffTag.TRANSFERFUNCTION, 4, TiffType.SHORT);

            copyTag(inImage, outImage, TiffTag.COLORMAP, 4, TiffType.SHORT);

            /* SMinSampleValue & SMaxSampleValue */
            switch (m_compression)
            {
                case Compression.JPEG:
                    outImage.SetField(TiffTag.JPEGQUALITY, m_quality);
                    outImage.SetField(TiffTag.JPEGCOLORMODE, m_jpegcolormode);
                    break;
                case Compression.LZW:
                case Compression.ADOBE_DEFLATE:
                case Compression.DEFLATE:
                    if (m_predictor != -1)
                        outImage.SetField(TiffTag.PREDICTOR, m_predictor);
                    else
                    {
                        result = inImage.GetField(TiffTag.PREDICTOR);
                        if (result != null)
                        {
                            m_predictor = result[0].ToShort();
                            outImage.SetField(TiffTag.PREDICTOR, m_predictor);
                        }
                    }
                    break;
                case Compression.CCITTFAX3:
                case Compression.CCITTFAX4:
                    if (m_compression == Compression.CCITTFAX3)
                    {
                        if (m_g3opts != Group3Opt.UNKNOWN)
                            outImage.SetField(TiffTag.GROUP3OPTIONS, m_g3opts);
                        else
                        {
                            result = inImage.GetField(TiffTag.GROUP3OPTIONS);
                            if (result != null)
                            {
                                m_g3opts = (Group3Opt)result[0].ToShort();
                                outImage.SetField(TiffTag.GROUP3OPTIONS, m_g3opts);
                            }
                        }
                    }
                    else
                        copyTag(inImage, outImage, TiffTag.GROUP4OPTIONS, 1, TiffType.LONG);

                    copyTag(inImage, outImage, TiffTag.BADFAXLINES, 1, TiffType.LONG);
                    copyTag(inImage, outImage, TiffTag.CLEANFAXDATA, 1, TiffType.LONG);
                    copyTag(inImage, outImage, TiffTag.CONSECUTIVEBADFAXLINES, 1, TiffType.LONG);
                    copyTag(inImage, outImage, TiffTag.FAXRECVPARAMS, 1, TiffType.LONG);
                    copyTag(inImage, outImage, TiffTag.FAXRECVTIME, 1, TiffType.LONG);
                    copyTag(inImage, outImage, TiffTag.FAXSUBADDRESS, 1, TiffType.ASCII);
                    break;
            }

            result = inImage.GetField(TiffTag.ICCPROFILE);
            if (result != null)
                outImage.SetField(TiffTag.ICCPROFILE, result[0], result[1]);

            result = inImage.GetField(TiffTag.NUMBEROFINKS);
            if (result != null)
            {
                short ninks = result[0].ToShort();
                outImage.SetField(TiffTag.NUMBEROFINKS, ninks);

                result = inImage.GetField(TiffTag.INKNAMES);
                if (result != null)
                {
                    string inknames = result[0].ToString();
                    string[] parts = inknames.Split(new char[] { '\0' });

                    int inknameslen = 0;
                    foreach (string part in parts)
                        inknameslen += part.Length + 1;

                    outImage.SetField(TiffTag.INKNAMES, inknameslen, inknames);
                }
            }

            result = inImage.GetField(TiffTag.PAGENUMBER);
            if (m_pageInSeq == 1)
            {
                if (m_pageNum < 0)
                {
                    /* only one input file */ 
                    if (result != null) 
                        outImage.SetField(TiffTag.PAGENUMBER, result[0], result[1]);
                }
                else
                {
                    outImage.SetField(TiffTag.PAGENUMBER, m_pageNum++, 0);
                }
            }
            else
            {
                if (result != null)
                {
                    if (m_pageNum < 0)
                    {
                        /* only one input file */
                        outImage.SetField(TiffTag.PAGENUMBER, result[0], result[1]);
                    }
                    else
                    {
                        outImage.SetField(TiffTag.PAGENUMBER, m_pageNum++, 0);
                    }
                }
            }

            int NTAGS = g_tags.Length;
            for (int i = 0; i < NTAGS; i++)
            {
                tagToCopy p = g_tags[i];
                copyTag(inImage, outImage, p.tag, p.count, p.type);
            }

            return pickFuncAndCopy(inImage, outImage, bitspersample, samplesperpixel, length, width);
        }
Esempio n. 3
0
 private static void copyTag(Tiff inImage, Tiff outImage, TiffTag tag, short count, TiffType type)
 {
     FieldValue[] result = null;
     switch (type)
     {
         case TiffType.SHORT:
             result = inImage.GetField(tag);
             if (result != null)
             {
                 if (count == 1)
                     outImage.SetField(tag, result[0]);
                 else if (count == 2)
                     outImage.SetField(tag, result[0], result[1]);
                 else if (count == 4)
                     outImage.SetField(tag, result[0], result[1], result[2]);
                 else if (count == -1)
                     outImage.SetField(tag, result[0], result[1]);
             }
             break;
         case TiffType.LONG:
             result = inImage.GetField(tag);
             if (result != null)
                 outImage.SetField(tag, result[0]);
             break;
         case TiffType.RATIONAL:
             result = inImage.GetField(tag);
             if (result != null)
                 outImage.SetField(tag, result[0]);
             break;
         case TiffType.ASCII:
             result = inImage.GetField(tag);
             if (result != null)
                 outImage.SetField(tag, result[0]);
             break;
         case TiffType.DOUBLE:
             result = inImage.GetField(tag);
             if (result != null)
                 outImage.SetField(tag, result[0]);
             break;
         default:
             Tiff.Error(inImage.FileName(),
                 "Data type {0} is not supported, tag {1} skipped.", tag, type);
             break;
     }
 }
Esempio n. 4
0
        static bool cvt_by_tile(Tiff inImage, Tiff outImage, int width, int height)
        {
            int tile_width = 0;
            int tile_height = 0;

            FieldValue[] result = inImage.GetField(TiffTag.TILEWIDTH);
            if (result != null)
            {
                tile_width = result[0].ToInt();

                result = inImage.GetField(TiffTag.TILELENGTH);
                if (result != null)
                    tile_height = result[0].ToInt();
            }

            if (result == null)
            {
                Tiff.Error(inImage.FileName(), "Source image not tiled");
                return false;
            }

            outImage.SetField(TiffTag.TILEWIDTH, tile_width);
            outImage.SetField(TiffTag.TILELENGTH, tile_height);

            // Allocate tile buffer
            int raster_size = multiply(tile_width, tile_height);
            int rasterByteSize = multiply(raster_size, sizeof(int));
            if (raster_size == 0 || rasterByteSize == 0)
            {
                Tiff.Error(inImage.FileName(),
                    "Can't allocate buffer for raster of size {0}x{1}", tile_width, tile_height);
                return false;
            }

            int[] raster = new int[raster_size];
            byte[] rasterBytes = new byte[rasterByteSize];

            // Allocate a scanline buffer for swapping during the vertical mirroring pass.
            // (Request can't overflow given prior checks.)
            int[] wrk_line = new int[tile_width];

            // Loop over the tiles.
            for (int row = 0; row < height; row += tile_height)
            {
                for (int col = 0; col < width; col += tile_width)
                {
                    // Read the tile into an RGBA array
                    if (!inImage.ReadRGBATile(col, row, raster))
                        return false;

                    // For some reason the ReadRGBATile() function chooses the lower left corner
                    // as the origin. Vertically mirror scanlines.
                    for (int i_row = 0; i_row < tile_height / 2; i_row++)
                    {
                        int topIndex = tile_width * i_row * sizeof(int);
                        int bottomIndex = tile_width * (tile_height - i_row - 1) * sizeof(int);

                        Buffer.BlockCopy(raster, topIndex, wrk_line, 0, tile_width * sizeof(int));
                        Buffer.BlockCopy(raster, bottomIndex, raster, topIndex, tile_width * sizeof(int));
                        Buffer.BlockCopy(wrk_line, 0, raster, bottomIndex, tile_width * sizeof(int));
                    }

                    // Write out the result in a tile.
                    int tile = outImage.ComputeTile(col, row, 0, 0);
                    Buffer.BlockCopy(raster, 0, rasterBytes, 0, rasterByteSize);
                    if (outImage.WriteEncodedTile(tile, rasterBytes, rasterByteSize) == -1)
                        return false;
                }
            }

            return true;
        }
Esempio n. 5
0
        public bool tiffcvt(Tiff inImage, Tiff outImage)
        {
            FieldValue[] result = inImage.GetField(TiffTag.IMAGEWIDTH);
            if (result == null)
                return false;
            int width = result[0].ToInt();

            result = inImage.GetField(TiffTag.IMAGELENGTH);
            if (result == null)
                return false;
            int height = result[0].ToInt();

            copyField(inImage, outImage, TiffTag.SUBFILETYPE);
            outImage.SetField(TiffTag.IMAGEWIDTH, width);
            outImage.SetField(TiffTag.IMAGELENGTH, height);
            outImage.SetField(TiffTag.BITSPERSAMPLE, 8);
            outImage.SetField(TiffTag.COMPRESSION, m_compression);
            outImage.SetField(TiffTag.PHOTOMETRIC, Photometric.RGB);

            copyField(inImage, outImage, TiffTag.FILLORDER);
            outImage.SetField(TiffTag.ORIENTATION, Orientation.TOPLEFT);

            if (m_noAlpha)
                outImage.SetField(TiffTag.SAMPLESPERPIXEL, 3);
            else
                outImage.SetField(TiffTag.SAMPLESPERPIXEL, 4);

            if (!m_noAlpha)
            {
                short[] v = new short[1];
                v[0] = (short)ExtraSample.ASSOCALPHA;
                outImage.SetField(TiffTag.EXTRASAMPLES, 1, v);
            }

            copyField(inImage, outImage, TiffTag.XRESOLUTION);
            copyField(inImage, outImage, TiffTag.YRESOLUTION);
            copyField(inImage, outImage, TiffTag.RESOLUTIONUNIT);
            outImage.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);

            if (!m_testFriendly)
                outImage.SetField(TiffTag.SOFTWARE, Tiff.GetVersion());

            copyField(inImage, outImage, TiffTag.DOCUMENTNAME);
            
            if (m_processByBlock && inImage.IsTiled())
                return cvt_by_tile(inImage, outImage, width, height);
            else if (m_processByBlock)
                return cvt_by_strip(inImage, outImage, width, height);

            return cvt_whole_image(inImage, outImage, width, height);
        }
Esempio n. 6
0
 private static void copyField(Tiff inImage, Tiff outImage, TiffTag tag)
 {
     FieldValue[] result = inImage.GetField(tag);
     if (result != null)
         outImage.SetField(tag, result[0]);
 }
Esempio n. 7
0
        /// <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;
        }
Esempio n. 8
0
        private bool cvt_by_strip(Tiff inImage, Tiff outImage, int width, int height)
        {
            FieldValue[] result = inImage.GetField(TiffTag.ROWSPERSTRIP);
            if (result == null)
            {
                Tiff.Error(inImage.FileName(), "Source image not in strips");
                return false;
            }

            m_rowsPerStrip = result[0].ToInt();
            outImage.SetField(TiffTag.ROWSPERSTRIP, m_rowsPerStrip);

            // Allocate strip buffer
            int raster_size = multiply(width, m_rowsPerStrip);
            int rasterByteSize = multiply(raster_size, sizeof(int));
            if (raster_size == 0 || rasterByteSize == 0)
            {
                Tiff.Error(inImage.FileName(),
                    "Can't allocate buffer for raster of size {0}x{1}", width, m_rowsPerStrip);
                return false;
            }

            int[] raster = new int[raster_size];
            byte[] rasterBytes = new byte[rasterByteSize];

            // Allocate a scanline buffer for swapping during the vertical mirroring pass.
            // (Request can't overflow given prior checks.)
            int[] wrk_line = new int[width];

            // Loop over the strips.
            for (int row = 0; row < height; row += m_rowsPerStrip)
            {
                // Read the strip into an RGBA array
                if (!inImage.ReadRGBAStrip(row, raster))
                    return false;

                // Figure out the number of scanlines actually in this strip.
                int rows_to_write;
                if (row + m_rowsPerStrip > height)
                    rows_to_write = height - row;
                else
                    rows_to_write = m_rowsPerStrip;

                // For some reason the TIFFReadRGBAStrip() function chooses the lower left corner
                // as the origin. Vertically mirror scanlines.
                for (int i_row = 0; i_row < rows_to_write / 2; i_row++)
                {
                    int topIndex = width * i_row * sizeof(int);
                    int bottomIndex = width * (rows_to_write - i_row - 1) * sizeof(int);

                    Buffer.BlockCopy(raster, topIndex, wrk_line, 0, width * sizeof(int));
                    Buffer.BlockCopy(raster, bottomIndex, raster, topIndex, width * sizeof(int));
                    Buffer.BlockCopy(wrk_line, 0, raster, bottomIndex, width * sizeof(int));
                }

                // Write out the result in a strip
                int bytesToWrite = rows_to_write * width * sizeof(int);
                Buffer.BlockCopy(raster, 0, rasterBytes, 0, bytesToWrite);
                if (outImage.WriteEncodedStrip(row / m_rowsPerStrip, rasterBytes, bytesToWrite) == -1)
                    return false;
            }

            return true;
        }
Esempio n. 9
0
        private static void convertToTiff(Bitmap bmp, Tiff tif, PixelFormat outputFormat)
        {
            if (outputFormat != PixelFormat.Format24bppRgb && outputFormat != PixelFormat.Format32bppArgb)
                throw new System.ArgumentOutOfRangeException();

            byte[] raster = getImageRasterBytes(bmp, outputFormat);
            tif.SetField(TiffTag.IMAGEWIDTH, bmp.Width);
            tif.SetField(TiffTag.IMAGELENGTH, bmp.Height);
            tif.SetField(TiffTag.COMPRESSION, Compression.LZW);
            tif.SetField(TiffTag.PHOTOMETRIC, Photometric.RGB);

            tif.SetField(TiffTag.ROWSPERSTRIP, bmp.Height);

            tif.SetField(TiffTag.XRESOLUTION, bmp.HorizontalResolution);
            tif.SetField(TiffTag.YRESOLUTION, bmp.VerticalResolution);

            tif.SetField(TiffTag.BITSPERSAMPLE, 8);
            if (outputFormat == PixelFormat.Format32bppArgb)
                tif.SetField(TiffTag.SAMPLESPERPIXEL, 4);
            else
                tif.SetField(TiffTag.SAMPLESPERPIXEL, 3);

            tif.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);

            int stride = raster.Length / bmp.Height;
            convertRGBSamples(raster, bmp.Width, bmp.Height, outputFormat);

            for (int i = 0, offset = 0; i < bmp.Height; i++)
            {
                bool res = tif.WriteScanline(raster, offset, i, 0);
                Assert.IsTrue(res);

                offset += stride;
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Creates new instance of the <see cref="TiffRgbaImage"/> class.
        /// </summary>
        /// <param name="tif">
        /// The instance of the <see cref="BitMiracle.LibTiff.Classic"/> class used to retrieve
        /// image data.
        /// </param>
        /// <param name="stopOnError">
        /// if set to <c>true</c> then an error will terminate the conversion; otherwise "get"
        /// methods will continue processing data until all the possible data in the image have
        /// been requested.
        /// </param>
        /// <param name="errorMsg">The error message (if any) gets placed here.</param>
        /// <returns>
        /// New instance of the <see cref="TiffRgbaImage"/> class if the image specified
        /// by <paramref name="tif"/> can be converted to RGBA format; otherwise, <c>null</c> is
        /// returned and <paramref name="errorMsg"/> contains the reason why it is being
        /// rejected.
        /// </returns>
        public static TiffRgbaImage Create(Tiff tif, bool stopOnError, out string errorMsg)
        {
            errorMsg = null;

            // Initialize to normal values
            TiffRgbaImage img = new TiffRgbaImage();
            img.row_offset = 0;
            img.col_offset = 0;
            img.redcmap = null;
            img.greencmap = null;
            img.bluecmap = null;
            img.req_orientation = Orientation.BOTLEFT; // It is the default
            img.tif = tif;
            img.stoponerr = stopOnError;

            FieldValue[] result = tif.GetFieldDefaulted(TiffTag.BITSPERSAMPLE);
            img.bitspersample = result[0].ToShort();
            switch (img.bitspersample)
            {
                case 1:
                case 2:
                case 4:
                case 8:
                case 16:
                    break;

                default:
                    errorMsg = string.Format(CultureInfo.InvariantCulture,
                        "Sorry, can not handle images with {0}-bit samples", img.bitspersample);
                    return null;
            }

            img.alpha = 0;
            result = tif.GetFieldDefaulted(TiffTag.SAMPLESPERPIXEL);
            img.samplesperpixel = result[0].ToShort();

            result = tif.GetFieldDefaulted(TiffTag.EXTRASAMPLES);
            short extrasamples = result[0].ToShort();
            byte[] sampleinfo = result[1].ToByteArray();

            if (extrasamples >= 1)
            {
                switch ((ExtraSample)sampleinfo[0])
                {
                    case ExtraSample.UNSPECIFIED:
                        if (img.samplesperpixel > 3)
                        {
                            // Workaround for some images without correct info about alpha channel
                            img.alpha = ExtraSample.ASSOCALPHA;
                        }
                        break;

                    case ExtraSample.ASSOCALPHA:
                        // data is pre-multiplied
                    case ExtraSample.UNASSALPHA:
                        // data is not pre-multiplied
                        img.alpha = (ExtraSample)sampleinfo[0];
                        break;
                }
            }

            if (Tiff.DEFAULT_EXTRASAMPLE_AS_ALPHA)
            {
                result = tif.GetField(TiffTag.PHOTOMETRIC);
                if (result == null)
                    img.photometric = Photometric.MINISWHITE;

                if (extrasamples == 0 && img.samplesperpixel == 4 && img.photometric == Photometric.RGB)
                {
                    img.alpha = ExtraSample.ASSOCALPHA;
                    extrasamples = 1;
                }
            }

            int colorchannels = img.samplesperpixel - extrasamples;

            result = tif.GetFieldDefaulted(TiffTag.COMPRESSION);
            Compression compress = (Compression)result[0].ToInt();

            result = tif.GetFieldDefaulted(TiffTag.PLANARCONFIG);
            PlanarConfig planarconfig = (PlanarConfig)result[0].ToShort();

            result = tif.GetField(TiffTag.PHOTOMETRIC);
            if (result == null)
            {
                switch (colorchannels)
                {
                    case 1:
                        if (img.isCCITTCompression())
                            img.photometric = Photometric.MINISWHITE;
                        else
                            img.photometric = Photometric.MINISBLACK;
                        break;

                    case 3:
                        img.photometric = Photometric.RGB;
                        break;

                    default:
                        errorMsg = string.Format(CultureInfo.InvariantCulture, "Missing needed {0} tag", photoTag);
                        return null;
                }
            }
            else
                img.photometric = (Photometric)result[0].ToInt();

            switch (img.photometric)
            {
                case Photometric.PALETTE:
                    result = tif.GetField(TiffTag.COLORMAP);
                    if (result == null)
                    {
                        errorMsg = string.Format(CultureInfo.InvariantCulture, "Missing required \"Colormap\" tag");
                        return null;
                    }

                    short[] red_orig = result[0].ToShortArray();
                    short[] green_orig = result[1].ToShortArray();
                    short[] blue_orig = result[2].ToShortArray();

                    // copy the colormaps so we can modify them
                    int n_color = (1 << img.bitspersample);
                    img.redcmap = new ushort[n_color];
                    img.greencmap = new ushort[n_color];
                    img.bluecmap = new ushort[n_color];

                    Buffer.BlockCopy(red_orig, 0, img.redcmap, 0, n_color * sizeof(ushort));
                    Buffer.BlockCopy(green_orig, 0, img.greencmap, 0, n_color * sizeof(ushort));
                    Buffer.BlockCopy(blue_orig, 0, img.bluecmap, 0, n_color * sizeof(ushort));

                    if (planarconfig == PlanarConfig.CONTIG &&
                        img.samplesperpixel != 1 && img.bitspersample < 8)
                    {
                        errorMsg = string.Format(CultureInfo.InvariantCulture,
                            "Sorry, can not handle contiguous data with {0}={1}, and {2}={3} and Bits/Sample={4}",
                            photoTag, img.photometric, "Samples/pixel", img.samplesperpixel, img.bitspersample);
                        return null;
                    }
                    break;

                case Photometric.MINISWHITE:
                case Photometric.MINISBLACK:
                    if (planarconfig == PlanarConfig.CONTIG &&
                        img.samplesperpixel != 1 && img.bitspersample < 8)
                    {
                        errorMsg = string.Format(CultureInfo.InvariantCulture,
                            "Sorry, can not handle contiguous data with {0}={1}, and {2}={3} and Bits/Sample={4}",
                            photoTag, img.photometric, "Samples/pixel", img.samplesperpixel, img.bitspersample);
                        return null;
                    }
                    break;

                case Photometric.YCBCR:
                    // It would probably be nice to have a reality check here.
                    if (planarconfig == PlanarConfig.CONTIG)
                    {
                        // can rely on LibJpeg.Net to convert to RGB
                        // XXX should restore current state on exit
                        switch (compress)
                        {
                            case Compression.JPEG:
                                // TODO: when complete tests verify complete desubsampling and
                                // YCbCr handling, remove use of JPEGCOLORMODE in favor of native
                                // handling
                                tif.SetField(TiffTag.JPEGCOLORMODE, JpegColorMode.RGB);
                                img.photometric = Photometric.RGB;
                                break;

                            default:
                                // do nothing
                                break;
                        }
                    }

                    // TODO: if at all meaningful and useful, make more complete support check
                    // here, or better still, refactor to let supporting code decide whether there
                    // is support and what meaningfull error to return
                    break;

                case Photometric.RGB:
                    if (colorchannels < 3)
                    {
                        errorMsg = string.Format(CultureInfo.InvariantCulture,
                            "Sorry, can not handle RGB image with {0}={1}", "Color channels", colorchannels);
                        return null;
                    }
                    break;

                case Photometric.SEPARATED:
                    result = tif.GetFieldDefaulted(TiffTag.INKSET);
                    InkSet inkset = (InkSet)result[0].ToByte();

                    if (inkset != InkSet.CMYK)
                    {
                        errorMsg = string.Format(CultureInfo.InvariantCulture,
                            "Sorry, can not handle separated image with {0}={1}", "InkSet", inkset);
                        return null;
                    }

                    if (img.samplesperpixel < 4)
                    {
                        errorMsg = string.Format(CultureInfo.InvariantCulture,
                            "Sorry, can not handle separated image with {0}={1}", "Samples/pixel", img.samplesperpixel);
                        return null;
                    }
                    break;

                case Photometric.LOGL:
                    if (compress != Compression.SGILOG)
                    {
                        errorMsg = string.Format(CultureInfo.InvariantCulture,
                            "Sorry, LogL data must have {0}={1}", "Compression", Compression.SGILOG);
                        return null;
                    }

                    tif.SetField(TiffTag.SGILOGDATAFMT, 3); // 8-bit RGB monitor values. 
                    img.photometric = Photometric.MINISBLACK; // little white lie
                    img.bitspersample = 8;
                    break;

                case Photometric.LOGLUV:
                    if (compress != Compression.SGILOG && compress != Compression.SGILOG24)
                    {
                        errorMsg = string.Format(CultureInfo.InvariantCulture,
                            "Sorry, LogLuv data must have {0}={1} or {2}", "Compression", Compression.SGILOG, Compression.SGILOG24);
                        return null;
                    }

                    if (planarconfig != PlanarConfig.CONTIG)
                    {
                        errorMsg = string.Format(CultureInfo.InvariantCulture,
                            "Sorry, can not handle LogLuv images with {0}={1}", "Planarconfiguration", planarconfig);
                        return null;
                    }

                    tif.SetField(TiffTag.SGILOGDATAFMT, 3); // 8-bit RGB monitor values. 
                    img.photometric = Photometric.RGB; // little white lie
                    img.bitspersample = 8;
                    break;

                case Photometric.CIELAB:
                    break;

                default:
                    errorMsg = string.Format(CultureInfo.InvariantCulture,
                        "Sorry, can not handle image with {0}={1}", photoTag, img.photometric);
                    return null;
            }

            img.Map = null;
            img.BWmap = null;
            img.PALmap = null;
            img.ycbcr = null;
            img.cielab = null;

            result = tif.GetField(TiffTag.IMAGEWIDTH);
            img.width = result[0].ToInt();

            result = tif.GetField(TiffTag.IMAGELENGTH);
            img.height = result[0].ToInt();

            result = tif.GetFieldDefaulted(TiffTag.ORIENTATION);
            img.orientation = (Orientation)result[0].ToByte();

            img.isContig = !(planarconfig == PlanarConfig.SEPARATE && colorchannels > 1);
            if (img.isContig)
            {
                if (!img.pickContigCase())
                {
                    errorMsg = "Sorry, can not handle image";
                    return null;
                }
            }
            else
            {
                if (!img.pickSeparateCase())
                {
                    errorMsg = "Sorry, can not handle image";
                    return null;
                }
            }

            return img;
        }
Esempio n. 11
0
        private static void SetTiffField(TiffInfo info, BitMiracle.LibTiff.Classic.Tiff image)
        {
            if (image == null)
            {
                throw new NullReferenceException("image");
            }

            // We need to set some values for basic tags before we can add any data
            image.SetField(TiffTag.IMAGEWIDTH, info.Width);
            image.SetField(TiffTag.IMAGELENGTH, info.Height);
            image.SetField(TiffTag.BITSPERSAMPLE, info.BitsPerSample);
            image.SetField(TiffTag.SAMPLESPERPIXEL, info.SamplesPerPixel);
            image.SetField(TiffTag.ORIENTATION, info.Orientation);
            image.SetField(TiffTag.ROWSPERSTRIP, info.Height);
            image.SetField(TiffTag.XRESOLUTION, info.XResolution);
            image.SetField(TiffTag.YRESOLUTION, info.YResolution);
            image.SetField(TiffTag.RESOLUTIONUNIT, info.ResolutionUnit);
            image.SetField(TiffTag.PLANARCONFIG, info.PlanarConfig);
            image.SetField(TiffTag.PHOTOMETRIC, info.Photometric);
            image.SetField(TiffTag.COMPRESSION, info.Compression);
            image.SetField(TiffTag.FILLORDER, info.FillOrder);
        }