예제 #1
0
        // Decode a tile/strip and apply the predictor routine.
        // Note that horizontal differencing must be done on a
        // row-by-row basis. The width of a "row" has already
        // been calculated at pre-decode time according to the
        // strip/tile dimensions.
        static bool PredictorDecodeTile(TIFF tif, byte[] op0, int occ0, ushort s)
        {
            TIFFPredictorState sp = (TIFFPredictorState)tif.tif_data;

            if (sp.decodetile(tif, op0, occ0, s))
            {
                int rowsize = sp.rowsize;
#if DEBUG
                if (rowsize <= 0)
                {
                    throw new Exception("rowsize<=0");
                }
#endif
                int op0_offset = 0;
                while (occ0 > 0)
                {
                    sp.decodepfunc(tif, op0, op0_offset, rowsize);
                    occ0       -= rowsize;
                    op0_offset += rowsize;
                }
                return(true);
            }

            return(false);
        }
예제 #2
0
        static bool TIFFPredictorInit(TIFF tif)
        {
            TIFFPredictorState sp = (TIFFPredictorState)tif.tif_data;

            // Merge codec-specific tag information.
            if (!_TIFFMergeFieldInfo(tif, predictFieldInfo))
            {
                TIFFErrorExt(tif.tif_clientdata, "TIFFPredictorInit", "Merging Predictor codec-specific tags failed");
                return(false);
            }

            // Override parent get/set field methods.
            sp.vgetparent = tif.tif_tagmethods.vgetfield;
            tif.tif_tagmethods.vgetfield = PredictorVGetField;                  // hook for predictor tag
            sp.vsetparent = tif.tif_tagmethods.vsetfield;
            tif.tif_tagmethods.vsetfield = PredictorVSetField;                  // hook for predictor tag
            sp.printdir = tif.tif_tagmethods.printdir;
            tif.tif_tagmethods.printdir = PredictorPrintDir;                    // hook for predictor tag

            sp.setupdecode      = tif.tif_setupdecode;
            tif.tif_setupdecode = PredictorSetupDecode;
            sp.setupencode      = tif.tif_setupencode;
            tif.tif_setupencode = PredictorSetupEncode;

            sp.predictor   = PREDICTOR.NONE;            // default value
            sp.encodepfunc = null;                      // no predictor routine
            sp.decodepfunc = null;                      // no predictor routine
            return(true);
        }
예제 #3
0
        static bool PredictorEncodeRow(TIFF tif, byte[] bp, int cc, ushort s)
        {
            TIFFPredictorState sp = (TIFFPredictorState)tif.tif_data;

            // XXX horizontal differencing alters user's data XXX
            sp.encodepfunc(tif, bp, 0, cc);
            return(sp.encoderow(tif, bp, cc, s));
        }
예제 #4
0
        static bool TIFFPredictorCleanup(TIFF tif)
        {
            TIFFPredictorState sp = (TIFFPredictorState)tif.tif_data;

            tif.tif_tagmethods.vgetfield = sp.vgetparent;
            tif.tif_tagmethods.vsetfield = sp.vsetparent;
            tif.tif_tagmethods.printdir  = sp.printdir;
            tif.tif_setupdecode          = sp.setupdecode;
            tif.tif_setupencode          = sp.setupencode;

            return(true);
        }
예제 #5
0
        // Decode a scanline and apply the predictor routine.
        static bool PredictorDecodeRow(TIFF tif, byte[] op0, int occ0, ushort s)
        {
            TIFFPredictorState sp = (TIFFPredictorState)tif.tif_data;

            if (sp.decoderow(tif, op0, occ0, s))
            {
                sp.decodepfunc(tif, op0, 0, occ0);
                return(true);
            }

            return(false);
        }
예제 #6
0
        static bool PredictorSetupEncode(TIFF tif)
        {
            TIFFPredictorState sp = (TIFFPredictorState)tif.tif_data;
            TIFFDirectory      td = tif.tif_dir;

            if (!sp.setupencode(tif) || !PredictorSetup(tif))
            {
                return(false);
            }

            if (sp.predictor == PREDICTOR.HORIZONTAL)
            {
                switch (td.td_bitspersample)
                {
                case 8: sp.encodepfunc = horDiff8; break;

                case 16: sp.encodepfunc = horDiff16; break;

                case 32: sp.encodepfunc = horDiff32; break;
                }

                // Override default encoding method with one that does the
                // predictor stuff.
                if (tif.tif_encoderow != PredictorEncodeRow)
                {
                    sp.encoderow        = tif.tif_encoderow;
                    tif.tif_encoderow   = PredictorEncodeRow;
                    sp.encodestrip      = tif.tif_encodestrip;
                    tif.tif_encodestrip = PredictorEncodeTile;
                    sp.encodetile       = tif.tif_encodetile;
                    tif.tif_encodetile  = PredictorEncodeTile;
                }
            }
            else if (sp.predictor == PREDICTOR.FLOATINGPOINT)
            {
                sp.encodepfunc = fpDiff;

                // Override default encoding method with one that does the
                // predictor stuff.
                if (tif.tif_encoderow != PredictorEncodeRow)
                {
                    sp.encoderow        = tif.tif_encoderow;
                    tif.tif_encoderow   = PredictorEncodeRow;
                    sp.encodestrip      = tif.tif_encodestrip;
                    tif.tif_encodestrip = PredictorEncodeTile;
                    sp.encodetile       = tif.tif_encodetile;
                    tif.tif_encodetile  = PredictorEncodeTile;
                }
            }

            return(true);
        }
예제 #7
0
        static bool PredictorVGetField(TIFF tif, TIFFTAG tag, object[] ap)
        {
            TIFFPredictorState sp = (TIFFPredictorState)tif.tif_data;

            switch (tag)
            {
            case TIFFTAG.PREDICTOR:
                ap[0] = (ushort)sp.predictor;
                break;

            default: return(sp.vgetparent(tif, tag, ap));
            }
            return(true);
        }
예제 #8
0
        static bool PredictorVSetField(TIFF tif, TIFFTAG tag, TIFFDataType dt, params object[] ap)
        {
            TIFFPredictorState sp = (TIFFPredictorState)tif.tif_data;

            switch (tag)
            {
            case TIFFTAG.PREDICTOR:
                sp.predictor = (PREDICTOR)__GetAsUshort(ap, 0);
                TIFFSetFieldBit(tif, FIELD.CODEC);
                break;

            default: return(sp.vsetparent(tif, tag, dt, ap));
            }
            tif.tif_flags |= TIF_FLAGS.TIFF_DIRTYDIRECT;

            return(true);
        }
예제 #9
0
        static bool PredictorSetup(TIFF tif)
        {
            string module = "PredictorSetup";

            TIFFPredictorState sp = (TIFFPredictorState)tif.tif_data;
            TIFFDirectory      td = tif.tif_dir;

            switch (sp.predictor)
            {
            case PREDICTOR.NONE: return(true);                    // no differencing

            case PREDICTOR.HORIZONTAL:
                if (td.td_bitspersample != 8 && td.td_bitspersample != 16 && td.td_bitspersample != 32)
                {
                    TIFFErrorExt(tif.tif_clientdata, module, "Horizontal differencing \"Predictor\" not supported with {0}-bit samples", td.td_bitspersample);
                    return(false);
                }
                break;

            case PREDICTOR.FLOATINGPOINT:
                if (td.td_sampleformat != SAMPLEFORMAT.IEEEFP)
                {
                    TIFFErrorExt(tif.tif_clientdata, module, "Floating point \"Predictor\" not supported with {0} data format", td.td_sampleformat);
                    return(false);
                }
                break;

            default:
                TIFFErrorExt(tif.tif_clientdata, module, "\"Predictor\" value {0} not supported", sp.predictor);
                return(false);
            }

            sp.stride = (td.td_planarconfig == PLANARCONFIG.CONTIG?(int)td.td_samplesperpixel:1);

            // Calculate the scanline/tile-width size in bytes.
            if (isTiled(tif))
            {
                sp.rowsize = TIFFTileRowSize(tif);
            }
            else
            {
                sp.rowsize = TIFFScanlineSize(tif);
            }

            return(true);
        }
예제 #10
0
        static bool PredictorEncodeTile(TIFF tif, byte[] bp0, int cc0, ushort s)
        {
            string             module = "PredictorEncodeTile";
            TIFFPredictorState sp     = (TIFFPredictorState)tif.tif_data;
            int cc = cc0;

            byte[] bp = null;
            try
            {
                bp = new byte[cc0];
            }
            catch
            {
                TIFFErrorExt(tif.tif_clientdata, module, "Out of memory allocating {0} byte temp buffer.", cc0);
                return(false);
            }

            bp0.CopyTo(bp, 0);

            int rowsize = sp.rowsize;

#if DEBUG
            if (rowsize <= 0)
            {
                throw new Exception("rowsize<=0");
            }
            if ((cc0 % rowsize) != 0)
            {
                throw new Exception("(cc0%rowsize)!=0");
            }
#endif

            int bp_offset = 0;
            while (cc > 0)
            {
                sp.encodepfunc(tif, bp, bp_offset, rowsize);
                cc        -= rowsize;
                bp_offset += rowsize;
            }

            return(sp.encodetile(tif, bp, cc0, s));
        }
예제 #11
0
        unsafe static void horDiff32(TIFF tif, byte[] cp0, int cp0_offset, int cc)
        {
            TIFFPredictorState sp = (TIFFPredictorState)tif.tif_data;
            int stride            = sp.stride;
            int wc = cc / 4;

            if (wc > stride)
            {
                fixed(byte *cp0_ = cp0)
                {
                    ushort *wp = (ushort *)(cp0_ + cp0_offset);

                    wc -= stride;
                    wp += wc - 1;
                    do
                    {
                        //was REPEAT4(stride, wp[stride]-=*(wp--));
                        switch (stride)
                        {
                        default: for (int i = stride - 4; i > 0; i--)
                            {
                                wp[stride] -= *(wp--);
                            }
                            goto case 4;

                        case 4: wp[stride] -= *(wp--); goto case 3;

                        case 3: wp[stride] -= *(wp--); goto case 2;

                        case 2: wp[stride] -= *(wp--); goto case 1;

                        case 1: wp[stride] -= *(wp--); break;

                        case 0: break;
                        }

                        wc -= stride;
                    }while(wc > 0);
                }
            }
        }
예제 #12
0
        static void PredictorPrintDir(TIFF tif, TextWriter fd, TIFFPRINT flags)
        {
            TIFFPredictorState sp = (TIFFPredictorState)tif.tif_data;

            if (TIFFFieldSet(tif, FIELD.CODEC))
            {
                fd.Write(" Predictor: ");
                switch (sp.predictor)
                {
                case PREDICTOR.NONE: fd.Write("none "); break;

                case PREDICTOR.HORIZONTAL: fd.Write("horizontal differencing "); break;

                case PREDICTOR.FLOATINGPOINT: fd.Write("floating point predictor "); break;
                }
                fd.WriteLine("{0} (0x{1:X2})\n", sp.predictor, sp.predictor);
            }
            if (sp.printdir != null)
            {
                sp.printdir(tif, fd, flags);
            }
        }
예제 #13
0
파일: tif_aux.cs 프로젝트: plynkus/libtiffN
        // Like TIFFGetField, but return any default
        // value if the tag is not present in the directory.
        //
        // NB:	We use the value in the directory, rather than
        //		explicit values so that defaults exist only in one
        //		place in the library -- in TIFFDefaultDirectory.
        public static bool TIFFVGetFieldDefaulted(TIFF tif, TIFFTAG tag, object[] ap)
        {
            TIFFDirectory td = tif.tif_dir;

            if (TIFFVGetField(tif, tag, ap))
            {
                return(true);
            }

            switch (tag)
            {
            case TIFFTAG.SUBFILETYPE:
                ap[0] = td.td_subfiletype;
                return(true);

            case TIFFTAG.BITSPERSAMPLE:
                ap[0] = td.td_bitspersample;
                return(true);

            case TIFFTAG.THRESHHOLDING:
                ap[0] = td.td_threshholding;
                return(true);

            case TIFFTAG.FILLORDER:
                ap[0] = td.td_fillorder;
                return(true);

            case TIFFTAG.ORIENTATION:
                ap[0] = td.td_orientation;
                return(true);

            case TIFFTAG.SAMPLESPERPIXEL:
                ap[0] = td.td_samplesperpixel;
                return(true);

            case TIFFTAG.ROWSPERSTRIP:
                ap[0] = td.td_rowsperstrip;
                return(true);

            case TIFFTAG.MINSAMPLEVALUE:
                ap[0] = td.td_minsamplevalue;
                return(true);

            case TIFFTAG.MAXSAMPLEVALUE:
                ap[0] = td.td_maxsamplevalue;
                return(true);

            case TIFFTAG.PLANARCONFIG:
                ap[0] = td.td_planarconfig;
                return(true);

            case TIFFTAG.RESOLUTIONUNIT:
                ap[0] = td.td_resolutionunit;
                return(true);

            case TIFFTAG.PREDICTOR:
                TIFFPredictorState sp = (TIFFPredictorState)tif.tif_data;
                ap[0] = sp.predictor;
                return(true);

            case TIFFTAG.DOTRANGE:
                ap[0] = 0;
                ap[1] = (1 << td.td_bitspersample) - 1;
                return(true);

            case TIFFTAG.INKSET:
                ap[0] = INKSET.CMYK;
                return(true);

            case TIFFTAG.NUMBEROFINKS:
                ap[0] = (ushort)4;
                return(true);

            case TIFFTAG.EXTRASAMPLES:
                ap[0] = td.td_extrasamples;
                ap[1] = td.td_sampleinfo;
                return(true);

            case TIFFTAG.MATTEING:
                ap[0] = (ushort)((td.td_extrasamples == 1 && td.td_sampleinfo[0] == (ushort)EXTRASAMPLE.ASSOCALPHA)?1:0);
                return(true);

            case TIFFTAG.TILEDEPTH:
                ap[0] = td.td_tiledepth;
                return(true);

            case TIFFTAG.DATATYPE:
                ap[0] = td.td_sampleformat - 1;
                return(true);

            case TIFFTAG.SAMPLEFORMAT:
                ap[0] = td.td_sampleformat;
                return(true);

            case TIFFTAG.IMAGEDEPTH:
                ap[0] = td.td_imagedepth;
                return(true);

            case TIFFTAG.YCBCRCOEFFICIENTS:
                // defaults are from CCIR Recommendation 601-1
                double[] ycbcrcoeffs = new double[] { 0.299, 0.587, 0.114 };
                ap[0] = ycbcrcoeffs;
                return(true);

            case TIFFTAG.YCBCRSUBSAMPLING:
                ap[0] = td.td_ycbcrsubsampling[0];
                ap[1] = td.td_ycbcrsubsampling[1];
                return(true);

            case TIFFTAG.YCBCRPOSITIONING:
                ap[0] = td.td_ycbcrpositioning;
                return(true);

            case TIFFTAG.WHITEPOINT:
                // TIFF 6.0 specification tells that it is no default
                // value for the WhitePoint, but AdobePhotoshop TIFF
                // Technical Note tells that it should be CIE D50.
                ap[0] = new double[] { D50_X0 / (D50_X0 + D50_Y0 + D50_Z0), D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0) };
                return(true);

            case TIFFTAG.TRANSFERFUNCTION:
                if (td.td_transferfunction[0] == null && !TIFFDefaultTransferFunction(td))
                {
                    TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "No space for \"TransferFunction\" tag");
                    return(false);
                }
                ap[0] = td.td_transferfunction[0];
                if (td.td_samplesperpixel - td.td_extrasamples > 1)
                {
                    ap[1] = td.td_transferfunction[1];
                    ap[2] = td.td_transferfunction[2];
                }
                return(true);

            case TIFFTAG.REFERENCEBLACKWHITE:
            {
                if (td.td_refblackwhite == null && !TIFFDefaultRefBlackWhite(td))
                {
                    return(false);
                }

                ap[0] = td.td_refblackwhite;
                return(true);
            }
            }
            return(false);
        }
예제 #14
0
        unsafe static void horDiff8(TIFF tif, byte[] cp0, int cp0_offset, int cc)
        {
            TIFFPredictorState sp = (TIFFPredictorState)tif.tif_data;
            int stride            = sp.stride;

            if (cc > stride)
            {
                fixed(byte *cp0_ = cp0)
                {
                    byte *cp = cp0_ + cp0_offset;

                    cc -= stride;

                    // Pipeline the most common cases.
                    if (stride == 3)
                    {
                        byte r1, g1, b1;
                        byte r2 = cp[0];
                        byte g2 = cp[1];
                        byte b2 = cp[2];
                        do
                        {
                            r1  = cp[3]; cp[3] -= r2; r2 = r1;
                            g1  = cp[4]; cp[4] -= g2; g2 = g1;
                            b1  = cp[5]; cp[5] -= b2; b2 = b1;
                            cp += 3;
                            cc -= 3;
                        }while(cc > 0);
                    }
                    else if (stride == 4)
                    {
                        byte r1, g1, b1, a1;
                        byte r2 = cp[0];
                        byte g2 = cp[1];
                        byte b2 = cp[2];
                        byte a2 = cp[3];
                        do
                        {
                            r1  = cp[4]; cp[4] -= r2; r2 = r1;
                            g1  = cp[5]; cp[5] -= g2; g2 = g1;
                            b1  = cp[6]; cp[6] -= b2; b2 = b1;
                            a1  = cp[7]; cp[7] -= a2; a2 = a1;
                            cp += 4;
                            cc -= 4;
                        }while(cc > 0);
                    }
                    else
                    {
                        cp += cc - 1;
                        do
                        {
                            //was REPEAT4(stride, cp[stride]-=*(cp--));
                            switch (stride)
                            {
                            default: for (int i = stride - 4; i > 0; i--)
                                {
                                    cp[stride] -= *(cp--);
                                }
                                goto case 4;

                            case 4: cp[stride] -= *(cp--); goto case 3;

                            case 3: cp[stride] -= *(cp--); goto case 2;

                            case 2: cp[stride] -= *(cp--); goto case 1;

                            case 1: cp[stride] -= *(cp--); break;

                            case 0: break;
                            }

                            cc -= stride;
                        }while(cc > 0);
                    }
                }
            }
        }
예제 #15
0
        static bool PredictorSetupDecode(TIFF tif)
        {
            TIFFPredictorState sp = (TIFFPredictorState)tif.tif_data;
            TIFFDirectory      td = tif.tif_dir;

            if (!sp.setupdecode(tif) || !PredictorSetup(tif))
            {
                return(false);
            }

            if (sp.predictor == PREDICTOR.HORIZONTAL)
            {
                switch (td.td_bitspersample)
                {
                case 8: sp.decodepfunc = horAcc8; break;

                case 16: sp.decodepfunc = horAcc16; break;

                case 32: sp.decodepfunc = horAcc32; break;
                }

                // Override default decoding method with one that does the
                // predictor stuff.
                if (tif.tif_decoderow != PredictorDecodeRow)
                {
                    sp.decoderow        = tif.tif_decoderow;
                    tif.tif_decoderow   = PredictorDecodeRow;
                    sp.decodestrip      = tif.tif_decodestrip;
                    tif.tif_decodestrip = PredictorDecodeTile;
                    sp.decodetile       = tif.tif_decodetile;
                    tif.tif_decodetile  = PredictorDecodeTile;
                }

                // If the data is horizontally differenced 16-bit data that
                // requires byte-swapping, then it must be byte swapped before
                // the accumulation step. We do this with a special-purpose
                // routine and override the normal post decoding logic that
                // the library setup when the directory was read.
                if ((tif.tif_flags & TIF_FLAGS.TIFF_SWAB) == TIF_FLAGS.TIFF_SWAB)
                {
                    if (sp.decodepfunc == horAcc16)
                    {
                        sp.decodepfunc     = swabHorAcc16;
                        tif.tif_postdecode = TIFFNoPostDecode;
                    }
                    else if (sp.decodepfunc == horAcc32)
                    {
                        sp.decodepfunc     = swabHorAcc32;
                        tif.tif_postdecode = TIFFNoPostDecode;
                    }
                }
            }
            else if (sp.predictor == PREDICTOR.FLOATINGPOINT)
            {
                sp.decodepfunc = fpAcc;

                // Override default decoding method with one that does the
                // predictor stuff.
                if (tif.tif_decoderow != PredictorDecodeRow)
                {
                    sp.decoderow        = tif.tif_decoderow;
                    tif.tif_decoderow   = PredictorDecodeRow;
                    sp.decodestrip      = tif.tif_decodestrip;
                    tif.tif_decodestrip = PredictorDecodeTile;
                    sp.decodetile       = tif.tif_decodetile;
                    tif.tif_decodetile  = PredictorDecodeTile;
                }

                // The data should not be swapped outside of the floating
                // point predictor, the accumulation routine should return
                // byres in the native order.
                if ((tif.tif_flags & TIF_FLAGS.TIFF_SWAB) == TIF_FLAGS.TIFF_SWAB)
                {
                    tif.tif_postdecode = TIFFNoPostDecode;
                }

                // Allocate buffer to keep the decoded bytes before
                // rearranging in the ight order
            }

            return(true);
        }