示例#1
0
        // Read the specified image into an ABGR-format rastertaking in account
        // specified orientation.
        public static bool TIFFReadRGBAImageOriented(TIFF tif, uint rwidth, uint rheight, uint[] raster, ORIENTATION orientation, bool stop)
        {
            string emsg="";
            TIFFRGBAImage img=new TIFFRGBAImage();
            bool ok;

            if(TIFFRGBAImageOK(tif, out emsg)&&TIFFRGBAImageBegin(img, tif, stop, out emsg))
            {
                img.req_orientation=orientation;
                // XXX verify rwidth and rheight against width and height
                ok=TIFFRGBAImageGet(img, raster, (rheight-img.height)*rwidth, rwidth, img.height);
                TIFFRGBAImageEnd(img);
            }
            else
            {
                TIFFErrorExt(tif.tif_clientdata, TIFFFileName(tif), emsg);
                ok=false;
            }

            return ok;
        }
示例#2
0
        // 8-bit packed YCbCr samples w/ no subsampling => RGB
        static void putcontig8bitYCbCr11tile(TIFFRGBAImage img, uint[] cp0, uint cp_offset, uint x, uint y, uint w, uint h, int fromskew, int toskew, byte[] pp0, uint pp_offset)
        {
            unsafe
            {
                fixed(uint* cp_=cp0)
                {
                    uint* cp=cp_+cp_offset;
                    fixed(byte* pp_=pp0)
                    {
                        byte* pp=pp_+pp_offset;

                        uint r, g, b;
                        fromskew*=3;
                        do
                        {
                            x=w; // was x = w>>1; patched 2000/09/25 [email protected]
                            do
                            {
                                int Cb=pp[1];
                                int Cr=pp[2];

                                TIFFYCbCrtoRGB(img.ycbcr, pp[0], Cb, Cr, out r, out g, out b); *cp++=(r|(g<<8)|(b<<16)|0xFF000000);

                                pp+=3;
                                x--;
                            } while(x!=0);

                            cp+=toskew;
                            pp+=fromskew;
                            h--;
                        } while(h!=0);

                    }
                }
            }
        }
示例#3
0
        // Read a whole strip off data from the file, and convert to RGBA form.
        // If this is the last strip, then it will only contain the portion of
        // the strip that is actually within the image space. The result is
        // organized in bottom to top form.
        public static bool TIFFReadRGBAStrip(TIFF tif, uint row, uint[] raster)
        {
            string emsg="";
            TIFFRGBAImage img=new TIFFRGBAImage();

            if(TIFFIsTiled(tif))
            {
                TIFFErrorExt(tif.tif_clientdata, TIFFFileName(tif), "Can't use TIFFReadRGBAStrip() with tiled file.");
                return false;
            }

            object[] ap=new object[2];
            TIFFGetFieldDefaulted(tif, TIFFTAG.ROWSPERSTRIP, ap); uint rowsperstrip=__GetAsUint(ap, 0);

            if((row%rowsperstrip)!=0)
            {
                TIFFErrorExt(tif.tif_clientdata, TIFFFileName(tif), "Row passed to TIFFReadRGBAStrip() must be first in a strip.");
                return false;
            }

            if(TIFFRGBAImageOK(tif, out emsg)&&TIFFRGBAImageBegin(img, tif, false, out emsg))
            {
                img.row_offset=(int)row;
                img.col_offset=0;

                uint rows_to_read;
                if(row+rowsperstrip>img.height) rows_to_read=img.height-row;
                else rows_to_read=rowsperstrip;

                bool ok=TIFFRGBAImageGet(img, raster, 0, img.width, rows_to_read);

                TIFFRGBAImageEnd(img);
                return ok;
            }
            else TIFFErrorExt(tif.tif_clientdata, TIFFFileName(tif), emsg);

            return false;
        }
示例#4
0
        // Get a strip-organized image that has
        //    PlanarConfiguration contiguous if SamplesPerPixel > 1
        // or
        //    SamplesPerPixel == 1
        static bool gtStripContig(TIFFRGBAImage img, uint[] raster, uint raster_offset, uint w, uint h)
        {
            TIFF tif=img.tif;
            byte[] buf;

            try
            {
                buf=new byte[TIFFStripSize(tif)];
            }
            catch
            {
                TIFFErrorExt(tif.tif_clientdata, TIFFFileName(tif), "No space for strip buffer");
                return false;
            }

            int flip=setorientation(img);
            int toskew;
            uint y;
            if((flip&FLIP_VERTICALLY)!=0)
            {
                y=h-1;
                toskew=-(int)(w+w);
            }
            else
            {
                y=0;
                toskew=-(int)(w-w);
            }

            object[] ap=new object[2];
            TIFFGetFieldDefaulted(tif, TIFFTAG.ROWSPERSTRIP, ap); uint rowsperstrip=__GetAsUint(ap, 0);
            TIFFGetFieldDefaulted(tif, TIFFTAG.YCBCRSUBSAMPLING, ap);
            ushort subsamplinghor=__GetAsUshort(ap, 0);
            ushort subsamplingver=__GetAsUshort(ap, 1);

            tileContigRoutine put=img.contig;
            uint nrow;
            bool ret=true;
            int scanline=TIFFNewScanlineSize(tif);
            uint imagewidth=img.width;
            int fromskew=(int)(w<imagewidth?imagewidth-w:0);
            for(uint row=0; row<h; row+=nrow)
            {
                uint rowstoread=(uint)(rowsperstrip-(row+img.row_offset)%rowsperstrip);
                nrow=(row+rowstoread>h?h-row:rowstoread);
                uint nrowsub=nrow;
                if((nrowsub%subsamplingver)!=0) nrowsub+=subsamplingver-nrowsub%subsamplingver;
                if(TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, (uint)(row+img.row_offset), 0), buf, (int)(((row+img.row_offset)%rowsperstrip+nrowsub)*scanline))<0&&img.stoponerr)
                {
                    ret=false;
                    break;
                }

                uint pos=(uint)(((row+img.row_offset)%rowsperstrip)*scanline);
                put(img, raster, raster_offset+y*w, 0, y, w, nrow, fromskew, toskew, buf, pos);

                if((flip&FLIP_VERTICALLY)!=0) y-=nrow;
                else y+=nrow;
            }

            if((flip&FLIP_HORIZONTALLY)!=0)
            {
                unsafe
                {
                    fixed(uint* raster_=raster)
                    {
                        for(uint line=0; line<h; line++)
                        {
                            uint* left=raster_+raster_offset+(line*w);
                            uint* right=left+w-1;

                            while(left<right)
                            {
                                uint temp=*left;
                                *left=*right;
                                *right=temp;
                                left++; right--;
                            }
                        }
                    }
                }
            }

            return ret;
        }
示例#5
0
        // Construct any mapping table used
        // by the associated put routine.
        static bool buildMap(TIFFRGBAImage img)
        {
            switch(img.photometric)
            {
                case PHOTOMETRIC.RGB:
                case PHOTOMETRIC.YCBCR:
                case PHOTOMETRIC.SEPARATED:
                    if(img.bitspersample==8) break;
                    if(!setupMap(img)) return false;
                    break;
                case PHOTOMETRIC.MINISBLACK:
                case PHOTOMETRIC.MINISWHITE:
                    if(!setupMap(img)) return false;
                    break;
                case PHOTOMETRIC.PALETTE:
                    // Convert 16-bit colormap to 8-bit (unless it looks
                    // like an old-style 8-bit colormap).
                    if(checkcmap(img)==16) cvtcmap(img);
                    else TIFFWarningExt(img.tif.tif_clientdata, TIFFFileName(img.tif), "Assuming 8-bit colormap");

                    // Use mapping table and colormap to construct
                    // unpacking tables for samples < 8 bits.
                    if(img.bitspersample<=8&&!makecmap(img)) return false;
                    break;
            }
            return true;
        }
示例#6
0
        static int setorientation(TIFFRGBAImage img)
        {
            switch(img.orientation)
            {
                case ORIENTATION.TOPLEFT:
                case ORIENTATION.LEFTTOP:
                    if(img.req_orientation==ORIENTATION.TOPRIGHT||img.req_orientation==ORIENTATION.RIGHTTOP) return FLIP_HORIZONTALLY;
                    else if(img.req_orientation==ORIENTATION.BOTRIGHT||img.req_orientation==ORIENTATION.RIGHTBOT) return FLIP_HORIZONTALLY|FLIP_VERTICALLY;
                    else if(img.req_orientation==ORIENTATION.BOTLEFT||img.req_orientation==ORIENTATION.LEFTBOT) return FLIP_VERTICALLY;
                    else return 0;
                case ORIENTATION.TOPRIGHT:
                case ORIENTATION.RIGHTTOP:
                    if(img.req_orientation==ORIENTATION.TOPLEFT||img.req_orientation==ORIENTATION.LEFTTOP) return FLIP_HORIZONTALLY;
                    else if(img.req_orientation==ORIENTATION.BOTRIGHT||img.req_orientation==ORIENTATION.RIGHTBOT) return FLIP_VERTICALLY;
                    else if(img.req_orientation==ORIENTATION.BOTLEFT||img.req_orientation==ORIENTATION.LEFTBOT) return FLIP_HORIZONTALLY|FLIP_VERTICALLY;
                    else return 0;
                case ORIENTATION.BOTRIGHT:
                case ORIENTATION.RIGHTBOT:
                    if(img.req_orientation==ORIENTATION.TOPLEFT||img.req_orientation==ORIENTATION.LEFTTOP) return FLIP_HORIZONTALLY|FLIP_VERTICALLY;
                    else if(img.req_orientation==ORIENTATION.TOPRIGHT||img.req_orientation==ORIENTATION.RIGHTTOP) return FLIP_VERTICALLY;
                    else if(img.req_orientation==ORIENTATION.BOTLEFT||img.req_orientation==ORIENTATION.LEFTBOT) return FLIP_HORIZONTALLY;
                    else return 0;
                case ORIENTATION.BOTLEFT:
                case ORIENTATION.LEFTBOT:
                    if(img.req_orientation==ORIENTATION.TOPLEFT||img.req_orientation==ORIENTATION.LEFTTOP) return FLIP_VERTICALLY;
                    else if(img.req_orientation==ORIENTATION.TOPRIGHT||img.req_orientation==ORIENTATION.RIGHTTOP) return FLIP_HORIZONTALLY|FLIP_VERTICALLY;
                    else if(img.req_orientation==ORIENTATION.BOTRIGHT||img.req_orientation==ORIENTATION.RIGHTBOT) return FLIP_HORIZONTALLY;
                    else return 0;
                default: return 0; // NOTREACHED

            }
        }
示例#7
0
        public static void TIFFRGBAImageEnd(TIFFRGBAImage img)
        {
            img.Map=null;
            img.BWmap=img.PALmap=null;
            img.ycbcr=null;
            img.cielab=null;

            img.redcmap=img.greencmap=img.bluecmap=null;
        }
示例#8
0
        // 8-bit greyscale => colormap/RGB
        static void putgreytile(TIFFRGBAImage img, uint[] cp0, uint cp_offset, uint x, uint y, uint w, uint h, int fromskew, int toskew, byte[] pp0, uint pp_offset)
        {
            int samplesperpixel=img.samplesperpixel;
            uint[][] BWmap=img.BWmap;

            unsafe
            {
                fixed(uint* cp_=cp0)
                {
                    uint* cp=cp_+cp_offset;
                    fixed(byte* pp_=pp0)
                    {
                        byte* pp=pp_+pp_offset;

                        while((h--)>0)
                        {
                            for(x=w; (x--)>0; )
                            {
                                *cp++=BWmap[*pp][0];
                                pp+=samplesperpixel;
                            }
                            cp+=toskew;
                            pp+=fromskew;
                        }
                    }
                }
            }
        }
示例#9
0
        // 16-bit packed samples => RGB
        static void putRGBcontig16bittile(TIFFRGBAImage img, uint[] cp0, uint cp_offset, uint x, uint y, uint w, uint h, int fromskew, int toskew, byte[] pp0, uint pp_offset)
        {
            int samplesperpixel=img.samplesperpixel*2;

            unsafe
            {
                fixed(uint* cp_=cp0)
                {
                    uint* cp=cp_+cp_offset;
                    fixed(byte* pp_=pp0)
                    {
                        byte* pp=pp_+pp_offset;

                        fromskew*=samplesperpixel;
                        while((h--)>0)
                        {
                            for(x=w; (x--)>0; )
                            {
                                *cp++=((uint)pp[1]|((uint)pp[3]<<8)|((uint)pp[5]<<16)|0xFF000000);
                                pp+=samplesperpixel;
                            }
                            cp+=toskew;
                            pp+=fromskew;
                        }
                    }
                }
            }
        }
示例#10
0
        // 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB
        static void putcontig8bitYCbCr41tile(TIFFRGBAImage img, uint[] cp0, uint cp_offset, uint x, uint y, uint w, uint h, int fromskew, int toskew, byte[] pp0, uint pp_offset)
        {
            unsafe
            {
                fixed(uint* cp_=cp0)
                {
                    uint* cp=cp_+cp_offset;
                    fixed(byte* pp_=pp0)
                    {
                        byte* pp=pp_+pp_offset;

                        uint r, g, b;

                        // XXX adjust fromskew
                        do
                        {
                            x=w>>2;
                            do
                            {
                                int Cb=pp[4];
                                int Cr=pp[5];

                                TIFFYCbCrtoRGB(img.ycbcr, pp[0], Cb, Cr, out r, out g, out b); cp[0]=(r|(g<<8)|(b<<16)|0xFF000000);
                                TIFFYCbCrtoRGB(img.ycbcr, pp[1], Cb, Cr, out r, out g, out b); cp[1]=(r|(g<<8)|(b<<16)|0xFF000000);
                                TIFFYCbCrtoRGB(img.ycbcr, pp[2], Cb, Cr, out r, out g, out b); cp[2]=(r|(g<<8)|(b<<16)|0xFF000000);
                                TIFFYCbCrtoRGB(img.ycbcr, pp[3], Cb, Cr, out r, out g, out b); cp[3]=(r|(g<<8)|(b<<16)|0xFF000000);

                                cp+=4;
                                pp+=6;
                                x--;
                            } while(x!=0);

                            if((w&3)!=0)
                            {
                                int Cb=pp[4];
                                int Cr=pp[5];

                                switch((w&3))
                                {
                                    case 3: TIFFYCbCrtoRGB(img.ycbcr, pp[2], Cb, Cr, out r, out g, out b); cp[2]=(r|(g<<8)|(b<<16)|0xFF000000); goto case 2;
                                    case 2: TIFFYCbCrtoRGB(img.ycbcr, pp[1], Cb, Cr, out r, out g, out b); cp[1]=(r|(g<<8)|(b<<16)|0xFF000000); goto case 1;
                                    case 1: TIFFYCbCrtoRGB(img.ycbcr, pp[0], Cb, Cr, out r, out g, out b); cp[0]=(r|(g<<8)|(b<<16)|0xFF000000); break;
                                    case 0: break;
                                }

                                cp+=(w&3);
                                pp+=6;
                            }

                            cp+=toskew;
                            pp+=fromskew;
                            h--;
                        } while(h!=0);
                    }
                }
            }
        }
示例#11
0
        // YCbCr => RGB conversion and packing routines.
        // 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB
        static void putcontig8bitYCbCr44tile(TIFFRGBAImage img, uint[] cp0, uint cp_offset, uint x, uint y, uint w, uint h, int fromskew, int toskew, byte[] pp0, uint pp_offset)
        {
            unsafe
            {
                fixed(uint* cp_=cp0)
                {
                    uint* cp=cp_+cp_offset;
                    fixed(byte* pp_=pp0)
                    {
                        byte* pp=pp_+pp_offset;

                        uint* cp1=cp+w+toskew;
                        uint* cp2=cp1+w+toskew;
                        uint* cp3=cp2+w+toskew;
                        int incr=3*(int)w+4*toskew;

                        // adjust fromskew
                        fromskew=(fromskew*18)/4;
                        if((h&3)==0&&(w&3)==0)
                        {
                            uint r, g, b;

                            for(; h>=4; h-=4)
                            {
                                x=w>>2;
                                do
                                {
                                    int Cb=pp[16];
                                    int Cr=pp[17];

                                    TIFFYCbCrtoRGB(img.ycbcr, pp[0], Cb, Cr, out r, out g, out b); cp[0]=(r|(g<<8)|(b<<16)|0xFF000000);
                                    TIFFYCbCrtoRGB(img.ycbcr, pp[1], Cb, Cr, out r, out g, out b); cp[1]=(r|(g<<8)|(b<<16)|0xFF000000);
                                    TIFFYCbCrtoRGB(img.ycbcr, pp[2], Cb, Cr, out r, out g, out b); cp[2]=(r|(g<<8)|(b<<16)|0xFF000000);
                                    TIFFYCbCrtoRGB(img.ycbcr, pp[3], Cb, Cr, out r, out g, out b); cp[3]=(r|(g<<8)|(b<<16)|0xFF000000);
                                    TIFFYCbCrtoRGB(img.ycbcr, pp[4], Cb, Cr, out r, out g, out b); cp1[0]=(r|(g<<8)|(b<<16)|0xFF000000);
                                    TIFFYCbCrtoRGB(img.ycbcr, pp[5], Cb, Cr, out r, out g, out b); cp1[1]=(r|(g<<8)|(b<<16)|0xFF000000);
                                    TIFFYCbCrtoRGB(img.ycbcr, pp[6], Cb, Cr, out r, out g, out b); cp1[2]=(r|(g<<8)|(b<<16)|0xFF000000);
                                    TIFFYCbCrtoRGB(img.ycbcr, pp[7], Cb, Cr, out r, out g, out b); cp1[3]=(r|(g<<8)|(b<<16)|0xFF000000);
                                    TIFFYCbCrtoRGB(img.ycbcr, pp[8], Cb, Cr, out r, out g, out b); cp2[0]=(r|(g<<8)|(b<<16)|0xFF000000);
                                    TIFFYCbCrtoRGB(img.ycbcr, pp[9], Cb, Cr, out r, out g, out b); cp2[1]=(r|(g<<8)|(b<<16)|0xFF000000);
                                    TIFFYCbCrtoRGB(img.ycbcr, pp[10], Cb, Cr, out r, out g, out b); cp2[2]=(r|(g<<8)|(b<<16)|0xFF000000);
                                    TIFFYCbCrtoRGB(img.ycbcr, pp[11], Cb, Cr, out r, out g, out b); cp2[3]=(r|(g<<8)|(b<<16)|0xFF000000);
                                    TIFFYCbCrtoRGB(img.ycbcr, pp[12], Cb, Cr, out r, out g, out b); cp3[0]=(r|(g<<8)|(b<<16)|0xFF000000);
                                    TIFFYCbCrtoRGB(img.ycbcr, pp[13], Cb, Cr, out r, out g, out b); cp3[1]=(r|(g<<8)|(b<<16)|0xFF000000);
                                    TIFFYCbCrtoRGB(img.ycbcr, pp[14], Cb, Cr, out r, out g, out b); cp3[2]=(r|(g<<8)|(b<<16)|0xFF000000);
                                    TIFFYCbCrtoRGB(img.ycbcr, pp[15], Cb, Cr, out r, out g, out b); cp3[3]=(r|(g<<8)|(b<<16)|0xFF000000);

                                    cp+=4; cp1+=4; cp2+=4; cp3+=4;
                                    pp+=18;
                                    x--;
                                } while(x!=0);
                                cp+=incr; cp1+=incr; cp2+=incr; cp3+=incr;
                                pp+=fromskew;
                            }
                        }
                        else
                        {
                            uint r, g, b;

                            while(h>0)
                            {
                                for(x=w; x>0; )
                                {
                                    int Cb=pp[16];
                                    int Cr=pp[17];

                                    switch(x)
                                    {
                                        default:
                                            switch(h)
                                            {
                                                default: TIFFYCbCrtoRGB(img.ycbcr, pp[15], Cb, Cr, out r, out g, out b); cp3[3]=(r|(g<<8)|(b<<16)|0xFF000000); goto case 3; // FALLTHROUGH
                                                case 3: TIFFYCbCrtoRGB(img.ycbcr, pp[11], Cb, Cr, out r, out g, out b); cp2[3]=(r|(g<<8)|(b<<16)|0xFF000000); goto case 2; // FALLTHROUGH
                                                case 2: TIFFYCbCrtoRGB(img.ycbcr, pp[7], Cb, Cr, out r, out g, out b); cp1[3]=(r|(g<<8)|(b<<16)|0xFF000000); goto case 1; // FALLTHROUGH
                                                case 1: TIFFYCbCrtoRGB(img.ycbcr, pp[3], Cb, Cr, out r, out g, out b); cp[3]=(r|(g<<8)|(b<<16)|0xFF000000); break;
                                            }
                                            goto case 3; // FALLTHROUGH
                                        case 3:
                                            switch(h)
                                            {
                                                default: TIFFYCbCrtoRGB(img.ycbcr, pp[14], Cb, Cr, out r, out g, out b); cp3[2]=(r|(g<<8)|(b<<16)|0xFF000000); goto case 3; // FALLTHROUGH
                                                case 3: TIFFYCbCrtoRGB(img.ycbcr, pp[10], Cb, Cr, out r, out g, out b); cp2[2]=(r|(g<<8)|(b<<16)|0xFF000000); goto case 2; // FALLTHROUGH
                                                case 2: TIFFYCbCrtoRGB(img.ycbcr, pp[6], Cb, Cr, out r, out g, out b); cp1[2]=(r|(g<<8)|(b<<16)|0xFF000000); goto case 1; // FALLTHROUGH
                                                case 1: TIFFYCbCrtoRGB(img.ycbcr, pp[2], Cb, Cr, out r, out g, out b); cp[2]=(r|(g<<8)|(b<<16)|0xFF000000); break;
                                            }
                                            goto case 2; // FALLTHROUGH
                                        case 2:
                                            switch(h)
                                            {
                                                default: TIFFYCbCrtoRGB(img.ycbcr, pp[13], Cb, Cr, out r, out g, out b); cp3[1]=(r|(g<<8)|(b<<16)|0xFF000000); goto case 3; // FALLTHROUGH
                                                case 3: TIFFYCbCrtoRGB(img.ycbcr, pp[9], Cb, Cr, out r, out g, out b); cp2[1]=(r|(g<<8)|(b<<16)|0xFF000000); goto case 2; // FALLTHROUGH
                                                case 2: TIFFYCbCrtoRGB(img.ycbcr, pp[5], Cb, Cr, out r, out g, out b); cp1[1]=(r|(g<<8)|(b<<16)|0xFF000000); goto case 1; // FALLTHROUGH
                                                case 1: TIFFYCbCrtoRGB(img.ycbcr, pp[1], Cb, Cr, out r, out g, out b); cp[1]=(r|(g<<8)|(b<<16)|0xFF000000); break;
                                            }
                                            goto case 1; // FALLTHROUGH
                                        case 1:
                                            switch(h)
                                            {
                                                default: TIFFYCbCrtoRGB(img.ycbcr, pp[12], Cb, Cr, out r, out g, out b); cp3[0]=(r|(g<<8)|(b<<16)|0xFF000000); goto case 3; // FALLTHROUGH
                                                case 3: TIFFYCbCrtoRGB(img.ycbcr, pp[8], Cb, Cr, out r, out g, out b); cp2[0]=(r|(g<<8)|(b<<16)|0xFF000000); goto case 2; // FALLTHROUGH
                                                case 2: TIFFYCbCrtoRGB(img.ycbcr, pp[4], Cb, Cr, out r, out g, out b); cp1[0]=(r|(g<<8)|(b<<16)|0xFF000000); goto case 1; // FALLTHROUGH
                                                case 1: TIFFYCbCrtoRGB(img.ycbcr, pp[0], Cb, Cr, out r, out g, out b); cp[0]=(r|(g<<8)|(b<<16)|0xFF000000); break;
                                            }
                                            break;
                                    }

                                    if(x<4)
                                    {
                                        cp+=x; cp1+=x; cp2+=x; cp3+=x;
                                        x=0;
                                    }
                                    else
                                    {
                                        cp+=4; cp1+=4; cp2+=4; cp3+=4;
                                        x-=4;
                                    }
                                    pp+=18;
                                }

                                if(h<=4) break;
                                h-=4;
                                cp+=incr; cp1+=incr; cp2+=incr; cp3+=incr;
                                pp+=fromskew;
                            }
                        }
                    }
                }
            }
        }
示例#12
0
        public static bool TIFFRGBAImageBegin(TIFFRGBAImage img, TIFF tif, bool stop, out string emsg)
        {
            // Initialize to normal values
            img.row_offset=0;
            img.col_offset=0;
            img.redcmap=img.greencmap=img.bluecmap=null;
            img.req_orientation=ORIENTATION.BOTLEFT;	// It is the default

            img.tif=tif;
            img.stoponerr=stop;

            object[] ap=new object[4];
            TIFFGetFieldDefaulted(tif, TIFFTAG.BITSPERSAMPLE, ap);
            img.bitspersample=__GetAsUshort(ap, 0);

            switch(img.bitspersample)
            {
                case 1:
                case 2:
                case 4:
                case 8:
                case 16: break;
                default:
                    emsg=string.Format("Sorry, can not handle images with {0}-bit samples", img.bitspersample);
                    return false;
            }
            img.alpha=0;
            TIFFGetFieldDefaulted(tif, TIFFTAG.SAMPLESPERPIXEL, ap);
            img.samplesperpixel=__GetAsUshort(ap, 0);

            TIFFGetFieldDefaulted(tif, TIFFTAG.EXTRASAMPLES, ap);
            ushort extrasamples=__GetAsUshort(ap, 0);
            ushort[] sampleinfo=(ushort[])ap[1];

            if(extrasamples>=1)
            {
                switch((EXTRASAMPLE)sampleinfo[0])
                {
                    case EXTRASAMPLE.UNSPECIFIED:	// Workaround for some images without
                        if(img.samplesperpixel>3)	// 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 DEFAULT_EXTRASAMPLE_AS_ALPHA
            if(!TIFFGetField(tif, TIFFTAG.PHOTOMETRIC, ap)) img.photometric=PHOTOMETRIC.MINISWHITE;
            else img.photometric=(PHOTOMETRIC)__GetAsUshort(ap, 0);

            if(extrasamples==0&&img.samplesperpixel==4&&img.photometric==PHOTOMETRIC.RGB)
            {
                img.alpha=EXTRASAMPLE.ASSOCALPHA;
                extrasamples=1;
            }
            #endif

            int colorchannels=img.samplesperpixel-extrasamples;
            TIFFGetFieldDefaulted(tif, TIFFTAG.COMPRESSION, ap);
            COMPRESSION compress=(COMPRESSION)__GetAsUshort(ap, 0);

            TIFFGetFieldDefaulted(tif, TIFFTAG.PLANARCONFIG, ap);
            PLANARCONFIG planarconfig=(PLANARCONFIG)__GetAsUshort(ap, 0);

            if(!TIFFGetField(tif, TIFFTAG.PHOTOMETRIC, ap))
            {
                switch(colorchannels)
                {
                    case 1:
                        if(isCCITTCompression(tif)) img.photometric=PHOTOMETRIC.MINISWHITE;
                        else img.photometric=PHOTOMETRIC.MINISBLACK;
                        break;
                    case 3:
                        img.photometric=PHOTOMETRIC.RGB;
                        break;
                    default:
                        emsg=string.Format("Missing needed {0} tag", photoTag);
                        return false;
                }
            }
            else img.photometric=(PHOTOMETRIC)__GetAsUshort(ap, 0);

            switch(img.photometric)
            {
                case PHOTOMETRIC.PALETTE:
                    ushort[] red_orig, green_orig, blue_orig;
                    if(!TIFFGetField(tif, TIFFTAG.COLORMAP, ap))
                    {
                        emsg="Missing required \"Colormap\" tag";
                        return false;
                    }

                    red_orig=ap[0] as ushort[];
                    green_orig=ap[1] as ushort[];
                    blue_orig=ap[2] as ushort[];

                    // copy the colormaps so we can modify them
                    int n_color=(1<<img.bitspersample);
                    try
                    {
                        img.redcmap=new ushort[n_color];
                        img.greencmap=new ushort[n_color];
                        img.bluecmap=new ushort[n_color];
                    }
                    catch
                    {
                        emsg="Out of memory for colormap copy";
                        return false;
                    }

                    Array.Copy(red_orig, img.redcmap, n_color);
                    Array.Copy(green_orig, img.greencmap, n_color);
                    Array.Copy(blue_orig, img.bluecmap, n_color);

                    goto case PHOTOMETRIC.MINISBLACK; // fall thru...
                case PHOTOMETRIC.MINISWHITE:
                case PHOTOMETRIC.MINISBLACK:
                    if(planarconfig==PLANARCONFIG.CONTIG&&img.samplesperpixel!=1&&img.bitspersample<8)
                    {
                        emsg=string.Format("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 false;
                    }
                    break;
                case PHOTOMETRIC.YCBCR:
                    // It would probably be nice to have a reality check here.
                    if(planarconfig==PLANARCONFIG.CONTIG)
                    {
                        // can rely on libjpeg 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 TIFFTAG_JPEGCOLORMODE in
                                // favor of tif_getimage.c native handling
                                TIFFSetField(tif, TIFFTAG.JPEGCOLORMODE, JPEGCOLORMODE.RGB);
                                img.photometric=PHOTOMETRIC.RGB;
                                break;
                            default: break; // do nothing
                        }
                    }
                    // 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)
                    {
                        emsg=string.Format("Sorry, can not handle RGB image with {0}={1}", "Color channels", colorchannels);
                        return false;
                    }
                    break;
                case PHOTOMETRIC.SEPARATED:
                    {
                        TIFFGetFieldDefaulted(tif, TIFFTAG.INKSET, ap);
                        INKSET inkset=(INKSET)__GetAsUshort(ap, 0);

                        if(inkset!=INKSET.CMYK)
                        {
                            emsg=string.Format("Sorry, can not handle separated image with {0}={1}", "InkSet", inkset);
                            return false;
                        }
                        if(img.samplesperpixel<4)
                        {
                            emsg=string.Format("Sorry, can not handle separated image with {0}={1}", "Samples/pixel", img.samplesperpixel);
                            return false;
                        }
                    }
                    break;
                case PHOTOMETRIC.LOGL:
                    if(compress!=COMPRESSION.SGILOG)
                    {
                        emsg=string.Format("Sorry, LogL data must have{0}={1}", "Compression", COMPRESSION.SGILOG);
                        return false;
                    }
                    TIFFSetField(tif, TIFFTAG.SGILOGDATAFMT, SGILOGDATAFMT._8BIT);
                    img.photometric=PHOTOMETRIC.MINISBLACK;	// little white lie
                    img.bitspersample=8;
                    break;
                case PHOTOMETRIC.LOGLUV:
                    if(compress!=COMPRESSION.SGILOG&&compress!=COMPRESSION.SGILOG24)
                    {
                        emsg=string.Format("Sorry, LogLuv data must have {0}={1} or {2}", "Compression", COMPRESSION.SGILOG, COMPRESSION.SGILOG24);
                        return false;
                    }
                    if(planarconfig!=PLANARCONFIG.CONTIG)
                    {
                        emsg=string.Format("Sorry, can not handle LogLuv images with {0}={1}", "Planarconfiguration", planarconfig);
                        return false;
                    }
                    TIFFSetField(tif, TIFFTAG.SGILOGDATAFMT, SGILOGDATAFMT._8BIT);
                    img.photometric=PHOTOMETRIC.RGB;		// little white lie
                    img.bitspersample=8;
                    break;
                case PHOTOMETRIC.CIELAB:
                    break;
                default:
                    emsg=string.Format("Sorry, can not handle image with {0}={1}", photoTag, img.photometric);
                    return false;
            }
            img.Map=null;
            img.BWmap=null;
            img.PALmap=null;
            img.ycbcr=null;
            img.cielab=null;

            TIFFGetField(tif, TIFFTAG.IMAGEWIDTH, ap); img.width=__GetAsUint(ap, 0);
            TIFFGetField(tif, TIFFTAG.IMAGELENGTH, ap); img.height=__GetAsUint(ap, 0);
            TIFFGetFieldDefaulted(tif, TIFFTAG.ORIENTATION, ap); img.orientation=(ORIENTATION)__GetAsUshort(ap, 0);

            img.isContig=!(planarconfig==PLANARCONFIG.SEPARATE&&colorchannels>1);
            if(img.isContig)
            {
                if(!PickContigCase(img))
                {
                    emsg="Sorry, can not handle image";
                    return false;
                }
            }
            else
            {
                if(!PickSeparateCase(img))
                {
                    emsg="Sorry, can not handle image";
                    return false;
                }
            }

            emsg="";
            return true;
        }
示例#13
0
        // 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB
        static void putcontig8bitYCbCr22tile(TIFFRGBAImage img, uint[] cp0, uint cp_offset, uint x, uint y, uint w, uint h, int fromskew, int toskew, byte[] pp0, uint pp_offset)
        {
            unsafe
            {
                fixed(uint* cp_=cp0)
                {
                    uint* cp=cp_+cp_offset;
                    fixed(byte* pp_=pp0)
                    {
                        byte* pp=pp_+pp_offset;

                        uint* cp2;
                        fromskew=(fromskew/2)*6;
                        cp2=cp+w+toskew;
                        while(h>=2)
                        {
                            x=w;
                            while(x>=2)
                            {
                                uint r, g, b;
                                int Cb=pp[4];
                                int Cr=pp[5];
                                TIFFYCbCrtoRGB(img.ycbcr, pp[0], Cb, Cr, out r, out g, out b); cp[0]=(r|(g<<8)|(b<<16)|0xFF000000);
                                TIFFYCbCrtoRGB(img.ycbcr, pp[1], Cb, Cr, out r, out g, out b); cp[1]=(r|(g<<8)|(b<<16)|0xFF000000);
                                TIFFYCbCrtoRGB(img.ycbcr, pp[2], Cb, Cr, out r, out g, out b); cp2[0]=(r|(g<<8)|(b<<16)|0xFF000000);
                                TIFFYCbCrtoRGB(img.ycbcr, pp[3], Cb, Cr, out r, out g, out b); cp2[1]=(r|(g<<8)|(b<<16)|0xFF000000);
                                cp+=2;
                                cp2+=2;
                                pp+=6;
                                x-=2;
                            }
                            if(x==1)
                            {
                                uint r, g, b;
                                int Cb=pp[4];
                                int Cr=pp[5];
                                TIFFYCbCrtoRGB(img.ycbcr, pp[0], Cb, Cr, out r, out g, out b); cp[0]=(r|(g<<8)|(b<<16)|0xFF000000);
                                TIFFYCbCrtoRGB(img.ycbcr, pp[2], Cb, Cr, out r, out g, out b); cp2[0]=(r|(g<<8)|(b<<16)|0xFF000000);
                                cp++;
                                cp2++;
                                pp+=6;
                            }
                            cp+=toskew*2+w;
                            cp2+=toskew*2+w;
                            pp+=fromskew;
                            h-=2;
                        }
                        if(h==1)
                        {
                            x=w;
                            while(x>=2)
                            {
                                uint r, g, b;
                                int Cb=pp[4];
                                int Cr=pp[5];
                                TIFFYCbCrtoRGB(img.ycbcr, pp[0], Cb, Cr, out r, out g, out b); cp[0]=(r|(g<<8)|(b<<16)|0xFF000000);
                                TIFFYCbCrtoRGB(img.ycbcr, pp[1], Cb, Cr, out r, out g, out b); cp[1]=(r|(g<<8)|(b<<16)|0xFF000000);
                                cp+=2;
                                cp2+=2;
                                pp+=6;
                                x-=2;
                            }
                            if(x==1)
                            {
                                uint r, g, b;
                                int Cb=pp[4];
                                int Cr=pp[5];
                                TIFFYCbCrtoRGB(img.ycbcr, pp[0], Cb, Cr, out r, out g, out b); cp[0]=(r|(g<<8)|(b<<16)|0xFF000000);
                            }
                        }
                    }
                }
            }
        }
示例#14
0
        // 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB
        static void putcontig8bitYCbCr21tile(TIFFRGBAImage img, uint[] cp0, uint cp_offset, uint x, uint y, uint w, uint h, int fromskew, int toskew, byte[] pp0, uint pp_offset)
        {
            unsafe
            {
                fixed(uint* cp_=cp0)
                {
                    uint* cp=cp_+cp_offset;
                    fixed(byte* pp_=pp0)
                    {
                        byte* pp=pp_+pp_offset;

                        uint r, g, b;
                        fromskew=(fromskew*4)/2;
                        do
                        {
                            x=w>>1;
                            do
                            {
                                int Cb=pp[2];
                                int Cr=pp[3];

                                TIFFYCbCrtoRGB(img.ycbcr, pp[0], Cb, Cr, out r, out g, out b); cp[0]=(r|(g<<8)|(b<<16)|0xFF000000);
                                TIFFYCbCrtoRGB(img.ycbcr, pp[1], Cb, Cr, out r, out g, out b); cp[1]=(r|(g<<8)|(b<<16)|0xFF000000);

                                cp+=2;
                                pp+=4;
                                x--;
                            } while(x!=0);

                            if((w&1)!=0)
                            {
                                int Cb=pp[2];
                                int Cr=pp[3];

                                TIFFYCbCrtoRGB(img.ycbcr, pp[0], Cb, Cr, out r, out g, out b); cp[0]=(r|(g<<8)|(b<<16)|0xFF000000);

                                cp+=1;
                                pp+=4;
                            }

                            cp+=toskew;
                            pp+=fromskew;
                            h--;
                        } while(h!=0);
                    }
                }
            }
        }
示例#15
0
        // 8-bit unpacked samples => RGBA w/ unassociated alpha
        static void putRGBUAseparate8bittile(TIFFRGBAImage img, uint[] cp0, uint cp_offset, uint x, uint y, uint w, uint h, int fromskew, int toskew, byte[] r0, byte[] g0, byte[] b0, byte[] a0, uint rgba_offset)
        {
            unsafe
            {
                fixed(uint* cp_=cp0)
                {
                    uint* cp=cp_+cp_offset;
                    fixed(byte* r_=r0, g_=g0, b_=b0, a_=a0)
                    {
                        byte* r=r_+rgba_offset;
                        byte* g=g_+rgba_offset;
                        byte* b=b_+rgba_offset;
                        byte* a=a_+rgba_offset;

                        while((h--)>0)
                        {
                            uint rv, gv, bv, av;
                            for(x=w; (x--)>0; )
                            {
                                av=*a++;
                                rv=(*r++*av+127)/255;
                                gv=(*g++*av+127)/255;
                                bv=(*b++*av+127)/255;
                                *cp++=(rv|(gv<<8)|(bv<<16)|(av<<24));
                            }

                            r+=fromskew; g+=fromskew; b+=fromskew; a+=fromskew;
                            cp+=toskew;
                        }
                    }
                }
            }
        }
示例#16
0
        // 8-bit packed CMYK samples w/Map => RGB
        //
        // NB: The conversion of CMYK=>RGB is *very* crude.
        static void putRGBcontig8bitCMYKMaptile(TIFFRGBAImage img, uint[] cp0, uint cp_offset, uint x, uint y, uint w, uint h, int fromskew, int toskew, byte[] pp0, uint pp_offset)
        {
            int samplesperpixel=img.samplesperpixel;
            byte[] Map=img.Map;

            unsafe
            {
                fixed(uint* cp_=cp0)
                {
                    uint* cp=cp_+cp_offset;
                    fixed(byte* pp_=pp0)
                    {
                        byte* pp=pp_+pp_offset;
                        ushort r, g, b, k;

                        fromskew*=samplesperpixel;
                        while((h--)>0)
                        {
                            for(x=w; (x--)>0; )
                            {
                                k=(ushort)(255-pp[3]);
                                r=(ushort)((k*(255-pp[0]))/255);
                                g=(ushort)((k*(255-pp[1]))/255);
                                b=(ushort)((k*(255-pp[2]))/255);
                                *cp++=((uint)Map[r]|((uint)Map[g]<<8)|((uint)Map[b]<<16)|0xFF000000);
                                pp+=samplesperpixel;
                            }
                            pp+=fromskew;
                            cp+=toskew;
                        }
                    }
                }
            }
        }
示例#17
0
        // 8-bit packed YCbCr samples w/ no subsampling => RGB
        static void putseparate8bitYCbCr11tile(TIFFRGBAImage img, uint[] cp0, uint cp_offset, uint x, uint y, uint w, uint h, int fromskew, int toskew, byte[] r0, byte[] g0, byte[] b0, byte[] a0, uint rgba_offset)
        {
            unsafe
            {
                fixed(uint* cp_=cp0)
                {
                    uint* cp=cp_+cp_offset;
                    fixed(byte* r_=r0, g_=g0, b_=b0)
                    {
                        byte* r=r_+rgba_offset;
                        byte* g=g_+rgba_offset;
                        byte* b=b_+rgba_offset;

                        // TODO: naming of input vars is still off, change obfuscating declaration inside define, or resolve obfuscation
                        while(h-->0)
                        {
                            x=w;
                            do
                            {
                                uint dr, dg, db;
                                TIFFYCbCrtoRGB(img.ycbcr, *r++, *g++, *b++, out dr, out dg, out db);
                                *cp++=(dr|(dg<<8)|(db<<16)|0xFF000000);
                                x--;
                            } while(x!=0);
                            r+=fromskew; g+=fromskew; b+=fromskew;
                            cp+=toskew;
                        }
                    }
                }
            }
        }
示例#18
0
        // 8-bit packed CMYK samples w/o Map => RGB
        //
        // NB: The conversion of CMYK=>RGB is *very* crude.
        static void putRGBcontig8bitCMYKtile(TIFFRGBAImage img, uint[] cp0, uint cp_offset, uint x, uint y, uint w, uint h, int fromskew, int toskew, byte[] pp0, uint pp_offset)
        {
            int samplesperpixel=img.samplesperpixel;

            unsafe
            {
                fixed(uint* cp_=cp0)
                {
                    uint* cp=cp_+cp_offset;
                    fixed(byte* pp_=pp0)
                    {
                        byte* pp=pp_+pp_offset;

                        uint r, g, b, k;

                        fromskew*=samplesperpixel;
                        while((h--)>0)
                        {
                            uint _x;
                            for(_x=w; _x>=8; _x-=8)
                            {
                                k=(uint)(255-pp[3]); r=(uint)((k*(255-pp[0]))/255); g=(uint)((k*(255-pp[1]))/255); b=(uint)((k*(255-pp[2]))/255); *cp++=(r|(g<<8)|(b<<16)|0xFF000000); pp+=samplesperpixel;
                                k=(uint)(255-pp[3]); r=(uint)((k*(255-pp[0]))/255); g=(uint)((k*(255-pp[1]))/255); b=(uint)((k*(255-pp[2]))/255); *cp++=(r|(g<<8)|(b<<16)|0xFF000000); pp+=samplesperpixel;
                                k=(uint)(255-pp[3]); r=(uint)((k*(255-pp[0]))/255); g=(uint)((k*(255-pp[1]))/255); b=(uint)((k*(255-pp[2]))/255); *cp++=(r|(g<<8)|(b<<16)|0xFF000000); pp+=samplesperpixel;
                                k=(uint)(255-pp[3]); r=(uint)((k*(255-pp[0]))/255); g=(uint)((k*(255-pp[1]))/255); b=(uint)((k*(255-pp[2]))/255); *cp++=(r|(g<<8)|(b<<16)|0xFF000000); pp+=samplesperpixel;
                                k=(uint)(255-pp[3]); r=(uint)((k*(255-pp[0]))/255); g=(uint)((k*(255-pp[1]))/255); b=(uint)((k*(255-pp[2]))/255); *cp++=(r|(g<<8)|(b<<16)|0xFF000000); pp+=samplesperpixel;
                                k=(uint)(255-pp[3]); r=(uint)((k*(255-pp[0]))/255); g=(uint)((k*(255-pp[1]))/255); b=(uint)((k*(255-pp[2]))/255); *cp++=(r|(g<<8)|(b<<16)|0xFF000000); pp+=samplesperpixel;
                                k=(uint)(255-pp[3]); r=(uint)((k*(255-pp[0]))/255); g=(uint)((k*(255-pp[1]))/255); b=(uint)((k*(255-pp[2]))/255); *cp++=(r|(g<<8)|(b<<16)|0xFF000000); pp+=samplesperpixel;
                                k=(uint)(255-pp[3]); r=(uint)((k*(255-pp[0]))/255); g=(uint)((k*(255-pp[1]))/255); b=(uint)((k*(255-pp[2]))/255); *cp++=(r|(g<<8)|(b<<16)|0xFF000000); pp+=samplesperpixel;
                            }

                            if(_x>0)
                            {
                                switch(_x)
                                {
                                    case 7: k=(uint)(255-pp[3]); r=(uint)((k*(255-pp[0]))/255); g=(uint)((k*(255-pp[1]))/255); b=(uint)((k*(255-pp[2]))/255); *cp++=(r|(g<<8)|(b<<16)|0xFF000000); pp+=samplesperpixel; goto case 6;
                                    case 6: k=(uint)(255-pp[3]); r=(uint)((k*(255-pp[0]))/255); g=(uint)((k*(255-pp[1]))/255); b=(uint)((k*(255-pp[2]))/255); *cp++=(r|(g<<8)|(b<<16)|0xFF000000); pp+=samplesperpixel; goto case 5;
                                    case 5: k=(uint)(255-pp[3]); r=(uint)((k*(255-pp[0]))/255); g=(uint)((k*(255-pp[1]))/255); b=(uint)((k*(255-pp[2]))/255); *cp++=(r|(g<<8)|(b<<16)|0xFF000000); pp+=samplesperpixel; goto case 4;
                                    case 4: k=(uint)(255-pp[3]); r=(uint)((k*(255-pp[0]))/255); g=(uint)((k*(255-pp[1]))/255); b=(uint)((k*(255-pp[2]))/255); *cp++=(r|(g<<8)|(b<<16)|0xFF000000); pp+=samplesperpixel; goto case 3;
                                    case 3: k=(uint)(255-pp[3]); r=(uint)((k*(255-pp[0]))/255); g=(uint)((k*(255-pp[1]))/255); b=(uint)((k*(255-pp[2]))/255); *cp++=(r|(g<<8)|(b<<16)|0xFF000000); pp+=samplesperpixel; goto case 2;
                                    case 2: k=(uint)(255-pp[3]); r=(uint)((k*(255-pp[0]))/255); g=(uint)((k*(255-pp[1]))/255); b=(uint)((k*(255-pp[2]))/255); *cp++=(r|(g<<8)|(b<<16)|0xFF000000); pp+=samplesperpixel; goto case 1;
                                    case 1: k=(uint)(255-pp[3]); r=(uint)((k*(255-pp[0]))/255); g=(uint)((k*(255-pp[1]))/255); b=(uint)((k*(255-pp[2]))/255); *cp++=(r|(g<<8)|(b<<16)|0xFF000000); pp+=samplesperpixel; break;
                                }
                            }

                            cp+=toskew;
                            pp+=fromskew;
                        }
                    }
                }
            }
        }
示例#19
0
        // Construct a mapping table to convert from the range
        // of the data samples to [0,255] --for display. This
        // process also handles inverting B&W images when needed.
        static bool setupMap(TIFFRGBAImage img)
        {
            int range=((1<<img.bitspersample)-1);

            // treat 16 bit the same as eight bit
            if(img.bitspersample==16) range=255;

            try
            {
                img.Map=new byte[range+1];
            }
            catch
            {
                TIFFErrorExt(img.tif.tif_clientdata, TIFFFileName(img.tif), "No space for photometric conversion table");
                return false;
            }

            if(img.photometric==PHOTOMETRIC.MINISWHITE) for(int x=0; x<=range; x++) img.Map[x]=(byte)(((range-x)*255)/range);
            else for(int x=0; x<=range; x++) img.Map[x]=(byte)((x*255)/range);

            if(img.bitspersample<=16&&(img.photometric==PHOTOMETRIC.MINISBLACK||img.photometric==PHOTOMETRIC.MINISWHITE))
            {
                // Use photometric mapping table to construct
                // unpacking tables for samples <= 8 bits.
                if(!makebwmap(img)) return false;
                // no longer need Map, free it
                img.Map=null;
            }
            return true;
        }
示例#20
0
        // 8-bit packed samples, no Map => RGB
        static void putRGBcontig8bittile(TIFFRGBAImage img, uint[] cp0, uint cp_offset, uint x, uint y, uint w, uint h, int fromskew, int toskew, byte[] pp0, uint pp_offset)
        {
            int samplesperpixel=img.samplesperpixel;

            unsafe
            {
                fixed(uint* cp_=cp0)
                {
                    uint* cp=cp_+cp_offset;
                    fixed(byte* pp_=pp0)
                    {
                        byte* pp=pp_+pp_offset;

                        fromskew*=samplesperpixel;
                        while((h--)>0)
                        {
                            uint _x;
                            for(_x=w; _x>=8; _x-=8)
                            {
                                *cp++=((uint)pp[0]|((uint)pp[1]<<8)|((uint)pp[2]<<16)|0xFF000000); pp+=samplesperpixel;
                                *cp++=((uint)pp[0]|((uint)pp[1]<<8)|((uint)pp[2]<<16)|0xFF000000); pp+=samplesperpixel;
                                *cp++=((uint)pp[0]|((uint)pp[1]<<8)|((uint)pp[2]<<16)|0xFF000000); pp+=samplesperpixel;
                                *cp++=((uint)pp[0]|((uint)pp[1]<<8)|((uint)pp[2]<<16)|0xFF000000); pp+=samplesperpixel;
                                *cp++=((uint)pp[0]|((uint)pp[1]<<8)|((uint)pp[2]<<16)|0xFF000000); pp+=samplesperpixel;
                                *cp++=((uint)pp[0]|((uint)pp[1]<<8)|((uint)pp[2]<<16)|0xFF000000); pp+=samplesperpixel;
                                *cp++=((uint)pp[0]|((uint)pp[1]<<8)|((uint)pp[2]<<16)|0xFF000000); pp+=samplesperpixel;
                                *cp++=((uint)pp[0]|((uint)pp[1]<<8)|((uint)pp[2]<<16)|0xFF000000); pp+=samplesperpixel;
                            }

                            if(_x>0)
                            {
                                switch(_x)
                                {
                                    case 7: *cp++=((uint)pp[0]|((uint)pp[1]<<8)|((uint)pp[2]<<16)|0xFF000000); pp+=samplesperpixel; goto case 6;
                                    case 6: *cp++=((uint)pp[0]|((uint)pp[1]<<8)|((uint)pp[2]<<16)|0xFF000000); pp+=samplesperpixel; goto case 5;
                                    case 5: *cp++=((uint)pp[0]|((uint)pp[1]<<8)|((uint)pp[2]<<16)|0xFF000000); pp+=samplesperpixel; goto case 4;
                                    case 4: *cp++=((uint)pp[0]|((uint)pp[1]<<8)|((uint)pp[2]<<16)|0xFF000000); pp+=samplesperpixel; goto case 3;
                                    case 3: *cp++=((uint)pp[0]|((uint)pp[1]<<8)|((uint)pp[2]<<16)|0xFF000000); pp+=samplesperpixel; goto case 2;
                                    case 2: *cp++=((uint)pp[0]|((uint)pp[1]<<8)|((uint)pp[2]<<16)|0xFF000000); pp+=samplesperpixel; goto case 1;
                                    case 1: *cp++=((uint)pp[0]|((uint)pp[1]<<8)|((uint)pp[2]<<16)|0xFF000000); pp+=samplesperpixel; break;
                                }
                            }

                            cp+=toskew;
                            pp+=fromskew;
                        }
                    }
                }
            }
        }
示例#21
0
        public static bool TIFFRGBAImageGet(TIFFRGBAImage img, uint[] raster, uint raster_offset, uint w, uint h)
        {
            if(img.get==null)
            {
                TIFFErrorExt(img.tif.tif_clientdata, TIFFFileName(img.tif), "No \"get\" routine setup");
                return false;
            }

            if(img.contig==null&&img.separate==null)
            {
                TIFFErrorExt(img.tif.tif_clientdata, TIFFFileName(img.tif), "No \"put\" routine setupl; probably can not handle image format");
                return false;
            }

            return img.get(img, raster, raster_offset, w, h);
        }
示例#22
0
        // 16-bit unpacked samples => RGB
        static void putRGBseparate16bittile(TIFFRGBAImage img, uint[] cp0, uint cp_offset, uint x, uint y, uint w, uint h, int fromskew, int toskew, byte[] r0, byte[] g0, byte[] b0, byte[] a0, uint rgba_offset)
        {
            unsafe
            {
                fixed(uint* cp_=cp0)
                {
                    uint* cp=cp_+cp_offset;
                    fixed(byte* r_=r0, g_=g0, b_=b0)
                    {
                        byte* r=r_+rgba_offset+1; // +1 ignore LSB
                        byte* g=g_+rgba_offset+1;
                        byte* b=b_+rgba_offset+1;

                        while((h--)>0)
                        {
                            for(x=0; x<w; x++)
                            {
                                *cp++=((uint)*r|((uint)*g<<8)|((uint)*b<<16)|0xFF000000);
                                r+=2; g+=2; b+=2;
                            }

                            r+=2*fromskew; g+=2*fromskew; b+=2*fromskew;
                            cp+=toskew;
                        }
                    }
                }
            }
        }
示例#23
0
        static int checkcmap(TIFFRGBAImage img)
        {
            int n=1<<img.bitspersample;

            unsafe
            {
                fixed(ushort* r_=img.redcmap, g_=img.greencmap, b_=img.bluecmap)
                {
                    ushort* r=r_;
                    ushort* g=g_;
                    ushort* b=b_;

                    while((n--)>0)
                    {
                        if(*r++>=256||*g++>=256||*b++>=256) return 16;
                    }
                }
            }

            return 8;
        }
示例#24
0
        // 8-bit unpacked samples => RGB
        static void putRGBseparate8bittile(TIFFRGBAImage img, uint[] cp0, uint cp_offset, uint x, uint y, uint w, uint h, int fromskew, int toskew, byte[] r0, byte[] g0, byte[] b0, byte[] a0, uint rgba_offset)
        {
            unsafe
            {
                fixed(uint* cp_=cp0)
                {
                    uint* cp=cp_+cp_offset;
                    fixed(byte* r_=r0, g_=g0, b_=b0)
                    {
                        byte* r=r_+rgba_offset;
                        byte* g=g_+rgba_offset;
                        byte* b=b_+rgba_offset;

                        while((h--)>0)
                        {
                            uint _x;
                            for(_x=w; _x>=8; _x-=8)
                            {
                                *cp++=((uint)(*r++)|((uint)(*g++)<<8)|((uint)(*b++)<<16)|0xFF000000);
                                *cp++=((uint)(*r++)|((uint)(*g++)<<8)|((uint)(*b++)<<16)|0xFF000000);
                                *cp++=((uint)(*r++)|((uint)(*g++)<<8)|((uint)(*b++)<<16)|0xFF000000);
                                *cp++=((uint)(*r++)|((uint)(*g++)<<8)|((uint)(*b++)<<16)|0xFF000000);
                                *cp++=((uint)(*r++)|((uint)(*g++)<<8)|((uint)(*b++)<<16)|0xFF000000);
                                *cp++=((uint)(*r++)|((uint)(*g++)<<8)|((uint)(*b++)<<16)|0xFF000000);
                                *cp++=((uint)(*r++)|((uint)(*g++)<<8)|((uint)(*b++)<<16)|0xFF000000);
                                *cp++=((uint)(*r++)|((uint)(*g++)<<8)|((uint)(*b++)<<16)|0xFF000000);
                            }

                            if(_x>0)
                            {
                                switch(_x)
                                {
                                    case 7: *cp++=((uint)(*r++)|((uint)(*g++)<<8)|((uint)(*b++)<<16)|0xFF000000); goto case 6;
                                    case 6: *cp++=((uint)(*r++)|((uint)(*g++)<<8)|((uint)(*b++)<<16)|0xFF000000); goto case 5;
                                    case 5: *cp++=((uint)(*r++)|((uint)(*g++)<<8)|((uint)(*b++)<<16)|0xFF000000); goto case 4;
                                    case 4: *cp++=((uint)(*r++)|((uint)(*g++)<<8)|((uint)(*b++)<<16)|0xFF000000); goto case 3;
                                    case 3: *cp++=((uint)(*r++)|((uint)(*g++)<<8)|((uint)(*b++)<<16)|0xFF000000); goto case 2;
                                    case 2: *cp++=((uint)(*r++)|((uint)(*g++)<<8)|((uint)(*b++)<<16)|0xFF000000); goto case 1;
                                    case 1: *cp++=((uint)(*r++)|((uint)(*g++)<<8)|((uint)(*b++)<<16)|0xFF000000); break;
                                }
                            }

                            r+=fromskew; g+=fromskew; b+=fromskew;
                            cp+=toskew;
                        }
                    }
                }
            }
        }
示例#25
0
        static void cvtcmap(TIFFRGBAImage img)
        {
            ushort[] r=img.redcmap;
            ushort[] g=img.greencmap;
            ushort[] b=img.bluecmap;

            for(int i=(1<<img.bitspersample)-1; i>=0; i--)
            {
                r[i]>>=8;
                g[i]>>=8;
                b[i]>>=8;
            }
        }
示例#26
0
        // 8-bit packed samples => RGBA w/ unassociated alpha
        // (known to have Map == NULL)
        static void putRGBUAcontig8bittile(TIFFRGBAImage img, uint[] cp0, uint cp_offset, uint x, uint y, uint w, uint h, int fromskew, int toskew, byte[] pp0, uint pp_offset)
        {
            int samplesperpixel=img.samplesperpixel;

            unsafe
            {
                fixed(uint* cp_=cp0)
                {
                    uint* cp=cp_+cp_offset;
                    fixed(byte* pp_=pp0)
                    {
                        byte* pp=pp_+pp_offset;

                        fromskew*=samplesperpixel;
                        while((h--)>0)
                        {
                            uint r, g, b, a;
                            for(x=w; (x--)>0; )
                            {
                                a=pp[3];
                                r=(a*pp[0]+127)/255;
                                g=(a*pp[1]+127)/255;
                                b=(a*pp[2]+127)/255;
                                *cp++=(r|(g<<8)|(b<<16)|(a<<24));
                                pp+=samplesperpixel;
                            }
                            cp+=toskew;
                            pp+=fromskew;
                        }
                    }
                }
            }
        }
示例#27
0
        // Get a strip-organized image with
        //    SamplesPerPixel > 1
        //    PlanarConfiguration separated
        // We assume that all such images are RGB.
        static bool gtStripSeparate(TIFFRGBAImage img, uint[] raster, uint raster_offset, uint w, uint h)
        {
            TIFF tif=img.tif;
            tileSeparateRoutine put=img.separate;
            EXTRASAMPLE alpha=img.alpha;

            byte[] p0, p1, p2, pa=null;
            int stripsize=TIFFStripSize(tif);
            try
            {
                p0=new byte[stripsize];
                p1=new byte[stripsize];
                p2=new byte[stripsize];
                if(alpha!=0) pa=new byte[stripsize];
            }
            catch
            {
                TIFFErrorExt(tif.tif_clientdata, TIFFFileName(tif), "No space for strip buffer");
                return false;
            }

            int flip=setorientation(img);
            int toskew;
            uint y;
            if((flip&FLIP_VERTICALLY)!=0)
            {
                y=h-1;
                toskew=-(int)(w+w);
            }
            else
            {
                y=0;
                toskew=-(int)(w-w);
            }

            object[] ap=new object[2];

            TIFFGetFieldDefaulted(tif, TIFFTAG.ROWSPERSTRIP, ap); uint rowsperstrip=__GetAsUint(ap, 0);

            uint nrow;
            uint imagewidth=img.width;
            bool ret=true;

            int scanline=TIFFScanlineSize(tif);
            int fromskew=(int)(w<imagewidth?imagewidth-w:0);

            for(uint row=0; row<h; row+=nrow)
            {
                uint rowstoread=(uint)(rowsperstrip-(row+img.row_offset)%rowsperstrip);
                nrow=(row+rowstoread>h?h-row:rowstoread);
                uint offset_row=(uint)(row+img.row_offset);
                if(TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0), p0, (int)((row+img.row_offset)%rowsperstrip+nrow)*scanline)<0&&img.stoponerr)
                {
                    ret=false;
                    break;
                }
                if(TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1), p1, (int)((row+img.row_offset)%rowsperstrip+nrow)*scanline)<0&&img.stoponerr)
                {
                    ret=false;
                    break;
                }
                if(TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2), p2, (int)((row+img.row_offset)%rowsperstrip+nrow)*scanline)<0&&img.stoponerr)
                {
                    ret=false;
                    break;
                }
                if(alpha!=0)
                {
                    if(TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 3), pa, (int)((row+img.row_offset)%rowsperstrip+nrow)*scanline)<0&&img.stoponerr)
                    {
                        ret=false;
                        break;
                    }
                }

                uint pos=(uint)(((row+img.row_offset)%rowsperstrip)*scanline);
                put(img, raster, raster_offset+y*w, 0, y, w, nrow, fromskew, toskew, p0, p1, p2, pa, pos);

                if((flip&FLIP_VERTICALLY)!=0) y-=nrow;
                else y+=nrow;
            }

            if((flip&FLIP_HORIZONTALLY)!=0)
            {
                unsafe
                {
                    fixed(uint* raster_=raster)
                    {
                        for(uint line=0; line<h; line++)
                        {
                            uint* left=raster_+raster_offset+(line*w);
                            uint* right=left+w-1;

                            while(left<right)
                            {
                                uint temp=*left;
                                *left=*right;
                                *right=temp;
                                left++; right--;
                            }
                        }
                    }
                }
            }

            return ret;
        }
示例#28
0
        // 16-bit unpacked samples => RGBA w/ unassociated alpha
        static void putRGBUAseparate16bittile(TIFFRGBAImage img, uint[] cp0, uint cp_offset, uint x, uint y, uint w, uint h, int fromskew, int toskew, byte[] r0, byte[] g0, byte[] b0, byte[] a0, uint rgba_offset)
        {
            unsafe
            {
                fixed(uint* cp_=cp0)
                {
                    uint* cp=cp_+cp_offset;
                    fixed(byte* r_=r0, g_=g0, b_=b0, a_=a0)
                    {
                        byte* r=r_+rgba_offset;
                        byte* g=g_+rgba_offset;
                        byte* b=b_+rgba_offset;
                        byte* a=a_+rgba_offset;

                        ushort* wr=(ushort*)r;
                        ushort* wg=(ushort*)g;
                        ushort* wb=(ushort*)b;
                        ushort* wa=(ushort*)a;

                        while((h--)>0)
                        {
                            uint r1, g1, b1, a1;
                            for(x=w; (x--)>0; )
                            {
                                a1=W2B(*wa++);
                                r1=(a1*W2B(*wr++)+127)/255;
                                g1=(a1*W2B(*wg++)+127)/255;
                                b1=(a1*W2B(*wb++)+127)/255;
                                *cp++=(r1|(g1<<8)|(b1<<16)|(a1<<24));
                            }
                            wr+=fromskew; wg+=fromskew; wb+=fromskew; wa+=fromskew;
                            cp+=toskew;
                        }
                    }
                }
            }
        }
示例#29
0
        // Get an tile-organized image that has
        //    SamplesPerPixel > 1
        //    PlanarConfiguration separated
        // We assume that all such images are RGB.
        static bool gtTileSeparate(TIFFRGBAImage img, uint[] raster, uint raster_offset, uint w, uint h)
        {
            TIFF tif=img.tif;
            tileSeparateRoutine put=img.separate;
            EXTRASAMPLE alpha=img.alpha;

            byte[] p0, p1, p2, pa=null;
            int tilesize=TIFFTileSize(tif);
            try
            {
                p0=new byte[tilesize];
                p1=new byte[tilesize];
                p2=new byte[tilesize];
                if(alpha!=0) pa=new byte[tilesize];
            }
            catch
            {
                TIFFErrorExt(tif.tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
                return false;
            }

            object[] ap=new object[2];
            TIFFGetField(tif, TIFFTAG.TILEWIDTH, ap); uint tw=__GetAsUint(ap, 0);
            TIFFGetField(tif, TIFFTAG.TILELENGTH, ap); uint th=__GetAsUint(ap, 0);

            int flip=setorientation(img);
            int toskew;
            uint y;
            if((flip&FLIP_VERTICALLY)!=0)
            {
                y=h-1;
                toskew=-(int)(tw+w);
            }
            else
            {
                y=0;
                toskew=-(int)(tw-w);
            }

            uint pos;

            bool ret=true;
            uint nrow;
            for(uint row=0; row<h; row+=nrow)
            {
                uint rowstoread=(uint)(th-(row+img.row_offset)%th);
                nrow=(row+rowstoread>h?h-row:rowstoread);
                for(uint col=0; col<w; col+=tw)
                {
                    if(TIFFReadTile(tif, p0, (uint)(col+img.col_offset), (uint)(row+img.row_offset), 0, 0)<0&&img.stoponerr)
                    {
                        ret=false;
                        break;
                    }
                    if(TIFFReadTile(tif, p1, (uint)(col+img.col_offset), (uint)(row+img.row_offset), 0, 1)<0&&img.stoponerr)
                    {
                        ret=false;
                        break;
                    }
                    if(TIFFReadTile(tif, p2, (uint)(col+img.col_offset), (uint)(row+img.row_offset), 0, 2)<0&&img.stoponerr)
                    {
                        ret=false;
                        break;
                    }
                    if(alpha!=0)
                    {
                        if(TIFFReadTile(tif, pa, (uint)(col+img.col_offset), (uint)(row+img.row_offset), 0, 3)<0&&img.stoponerr)
                        {
                            ret=false;
                            break;
                        }
                    }

                    pos=(uint)(((row+img.row_offset)%th)*TIFFTileRowSize(tif));

                    if(col+tw>w)
                    {
                        // Tile is clipped horizontally. Calculate
                        // visible portion and skewing factors.
                        uint npix=w-col;
                        int fromskew=(int)(tw-npix);
                        put(img, raster, raster_offset+y*w+col, col, y, npix, nrow, fromskew, toskew+fromskew, p0, p1, p2, pa, pos);
                    }
                    else put(img, raster, raster_offset+y*w+col, col, y, tw, nrow, 0, toskew, p0, p1, p2, pa, pos);
                }

                if((flip&FLIP_VERTICALLY)!=0) y-=nrow;
                else y+=nrow;
            }

            if((flip&FLIP_HORIZONTALLY)!=0)
            {
                unsafe
                {
                    fixed(uint* raster_=raster)
                    {
                        for(uint line=0; line<h; line++)
                        {
                            uint* left=raster_+raster_offset+(line*w);
                            uint* right=left+w-1;

                            while(left<right)
                            {
                                uint temp=*left;
                                *left=*right;
                                *right=temp;
                                left++; right--;
                            }
                        }
                    }
                }
            }

            return ret;
        }
示例#30
0
        // 8-bit packed CIE L*a*b 1976 samples => RGB
        static void putcontig8bitCIELab(TIFFRGBAImage img, uint[] cp0, uint cp_offset, uint x, uint y, uint w, uint h, int fromskew, int toskew, byte[] pp0, uint pp_offset)
        {
            unsafe
            {
                fixed(uint* cp_=cp0)
                {
                    uint* cp=cp_+cp_offset;
                    fixed(byte* pp_=pp0)
                    {
                        byte* pp=pp_+pp_offset;

                        float X, Y, Z;
                        uint r, g, b;

                        fromskew*=3;
                        while((h--)>0)
                        {
                            for(x=w; (x--)>0; )
                            {
                                TIFFCIELabToXYZ(img.cielab, pp[0], pp[1], pp[2], out X, out Y, out Z);
                                TIFFXYZToRGB(img.cielab, X, Y, Z, out r, out g, out b);
                                *cp++=(r|(g<<8)|(b<<16)|0xFF000000);
                                pp+=3;
                            }
                            cp+=toskew;
                            pp+=fromskew;
                        }
                    }
                }
            }
        }