public static TIFF XTIFFClientOpen(string name, string mode, Stream thehandle, TIFFReadWriteProc RWProc, TIFFReadWriteProc RWProc2, TIFFSeekProc SProc, TIFFCloseProc CProc, TIFFSizeProc SzProc) { // Set up the callback XTIFFInitialize(); // Open the file; the callback will set everything up return libtiff.TIFFClientOpen(name, mode, thehandle, RWProc, RWProc2, SProc, CProc, SzProc); }
public static TIFF XTIFFClientOpen(string name, string mode, Stream thehandle, TIFFReadWriteProc RWProc, TIFFReadWriteProc RWProc2, TIFFSeekProc SProc, TIFFCloseProc CProc, TIFFSizeProc SzProc) { // Set up the callback XTIFFInitialize(); // Open the file; the callback will set everything up return(libtiff.TIFFClientOpen(name, mode, thehandle, RWProc, RWProc2, SProc, CProc, SzProc)); }
public static TIFF TIFFClientOpen(string name, string mode, Stream clientdata, TIFFReadWriteProc readproc, TIFFReadWriteProc writeproc, TIFFSeekProc seekproc, TIFFCloseProc closeproc, TIFFSizeProc sizeproc) { string module="TIFFClientOpen"; O m=TIFFgetMode(mode, module); if(m==O.ERROR) return null; TIFF tif=null; try { tif=new TIFF(); } catch { TIFFErrorExt(clientdata, module, "{0}: Out of memory (TIFF structure)", name); return null; } tif.tif_name=name; tif.tif_mode=m&~(O.CREAT|O.TRUNC); tif.tif_curdir=0xffff; // non-existent directory tif.tif_curoff=0; tif.tif_curstrip=0xffffffff; // invalid strip tif.tif_row=0xffffffff; // read/write pre-increment tif.tif_clientdata=clientdata; if(readproc==null||writeproc==null||seekproc==null||closeproc==null||sizeproc==null) { TIFFErrorExt(clientdata, module, "One of the client procedures is NULL pointer."); return null; } tif.tif_readproc=readproc; tif.tif_writeproc=writeproc; tif.tif_seekproc=seekproc; tif.tif_closeproc=closeproc; tif.tif_sizeproc=sizeproc; TIFFSetDefaultCompressionState(tif); // setup default state // Default is to return data MSB2LSB and enable the // use of memory-mapped files and strip chopping when // a file is opened read-only. tif.tif_flags=TIF_FLAGS.FILLORDER_MSB2LSB; #if STRIPCHOP_DEFAULT if(m==O.RDONLY||m==O.RDWR) tif.tif_flags|=TIF_FLAGS.TIFF_STRIPCHOP; #endif // Process library-specific flags in the open mode string. // The following flags may be used to control intrinsic library // behaviour that may or may not be desirable (usually for // compatibility with some application that claims to support // TIFF but only supports some braindead idea of what the // vendor thinks TIFF is): // // 'l' use little-endian byte order for creating a file // 'b' use big-endian byte order for creating a file // 'L' read/write information using LSB2MSB bit order // 'B' read/write information using MSB2LSB bit order // 'H' read/write information using host bit order // 'C' enable strip chopping support when reading // 'c' disable strip chopping support // 'h' read TIFF header only, do not load the first IFD // // The use of the 'l' and 'b' flags is strongly discouraged. // These flags are provided solely because numerous vendors, // typically on the PC, do not correctly support TIFF; they // only support the Intel little-endian byte order. This // support is not configured by default because it supports // the violation of the TIFF spec that says that readers *MUST* // support both byte orders. It is strongly recommended that // you not use this feature except to deal with busted apps // that write invalid TIFF. And even in those cases you should // bang on the vendors to fix their software. // // The 'L', 'B', and 'H' flags are intended for applications // that can optimize operations on data by using a particular // bit order. By default the library returns data in MSB2LSB // bit order for compatibiltiy with older versions of this // library. Returning data in the bit order of the native cpu // makes the most sense but also requires applications to check // the value of the FillOrder tag; something they probably do // not do right now. // // The 'C' and 'c' flags are provided because the library support // for chopping up large strips into multiple smaller strips is not // application-transparent and as such can cause problems. The 'c' // option permits applications that only want to look at the tags, // for example, to get the unadulterated TIFF tag information. foreach(char cp in mode) { switch(cp) { case 'b': if((m&O.CREAT)==O.CREAT) tif.tif_flags|=TIF_FLAGS.TIFF_SWAB; break; case 'l': break; case 'B': tif.tif_flags=(tif.tif_flags&~TIF_FLAGS.TIFF_FILLORDER)|TIF_FLAGS.FILLORDER_MSB2LSB; break; case 'L': tif.tif_flags=(tif.tif_flags&~TIF_FLAGS.TIFF_FILLORDER)|TIF_FLAGS.FILLORDER_LSB2MSB; break; case 'H': tif.tif_flags=(tif.tif_flags&~TIF_FLAGS.TIFF_FILLORDER)|HOST_FILLORDER; break; case 'C': if(m==O.RDONLY) tif.tif_flags|=TIF_FLAGS.TIFF_STRIPCHOP; break; case 'c': if(m==O.RDONLY) tif.tif_flags&=~TIF_FLAGS.TIFF_STRIPCHOP; break; case 'h': tif.tif_flags|=TIF_FLAGS.TIFF_HEADERONLY; break; } } // Read in TIFF header. if((tif.tif_mode&O.TRUNC)==O.TRUNC||!ReadOK(tif, tif.tif_header)) { if(tif.tif_mode==O.RDONLY) { TIFFErrorExt(tif.tif_clientdata, name, "Cannot read TIFF header"); goto bad; } // Setup header and write. tif.tif_header.tiff_magic=(tif.tif_flags&TIF_FLAGS.TIFF_SWAB)==TIF_FLAGS.TIFF_SWAB?TIFF_BIGENDIAN:TIFF_LITTLEENDIAN; tif.tif_header.tiff_version=TIFF_VERSION; if((tif.tif_flags&TIF_FLAGS.TIFF_SWAB)==TIF_FLAGS.TIFF_SWAB) TIFFSwab(ref tif.tif_header.tiff_version); tif.tif_header.tiff_diroff=0; // filled in later // The doc for "fopen" for some STD_C_LIBs says that if you // open a file for modify ("+"), then you must fseek (or // fflush?) between any freads and fwrites. This is not // necessary on most systems, but has been shown to be needed // on Solaris. TIFFSeekFile(tif, 0, SEEK.SET); if(!WriteOK(tif, tif.tif_header)) { TIFFErrorExt(tif.tif_clientdata, name, "Error writing TIFF header"); goto bad; } // Setup the byte order handling. TIFFInitOrder(tif, tif.tif_header.tiff_magic); // Setup default directory. if(!TIFFDefaultDirectory(tif)) goto bad; tif.tif_diroff=0; tif.tif_dirlist.Clear(); tif.tif_dirnumber=0; return tif; } // Setup the byte order handling. #if MDI_SUPPORT if(tif.tif_header.tiff_magic!=TIFF_BIGENDIAN&&tif.tif_header.tiff_magic!=TIFF_LITTLEENDIAN&&tif.tif_header.tiff_magic!=MDI_LITTLEENDIAN) { TIFFErrorExt(tif.tif_clientdata, name, "Not a TIFF or MDI file, bad magic number {0} (0x{1:X4})", tif.tif_header.tiff_magic, tif.tif_header.tiff_magic); goto bad; } #else if(tif.tif_header.tiff_magic!=TIFF_BIGENDIAN&&tif.tif_header.tiff_magic!=TIFF_LITTLEENDIAN) { TIFFErrorExt(tif.tif_clientdata, name, "Not a TIFF file, bad magic number {0} (0x{1:X4})", tif.tif_header.tiff_magic, tif.tif_header.tiff_magic); goto bad; } #endif TIFFInitOrder(tif, tif.tif_header.tiff_magic); // Swap header if required. if((tif.tif_flags&TIF_FLAGS.TIFF_SWAB)==TIF_FLAGS.TIFF_SWAB) { TIFFSwab(ref tif.tif_header.tiff_version); TIFFSwab(ref tif.tif_header.tiff_diroff); } // Now check version (if needed, it's been byte-swapped). // Note that this isn't actually a version number, it's a // magic number that doesn't change (stupid). if(tif.tif_header.tiff_version==TIFF_BIGTIFF_VERSION) { TIFFErrorExt(tif.tif_clientdata, name, "This is a BigTIFF file. This format not supported\nby this version of libtiff."); goto bad; } if(tif.tif_header.tiff_version!=TIFF_VERSION) { TIFFErrorExt(tif.tif_clientdata, name, "Not a TIFF file, bad version number {0} (0x{1:X4})", tif.tif_header.tiff_version, tif.tif_header.tiff_version); goto bad; } tif.tif_flags|=TIF_FLAGS.TIFF_MYBUFFER; tif.tif_rawcp=0; tif.tif_rawdata=null; tif.tif_rawdatasize=0; // Sometimes we do not want to read the first directory (for example, // it may be broken) and want to proceed to other directories. I this // case we use the TIFF_HEADERONLY flag to open file and return // immediately after reading TIFF header. if((tif.tif_flags&TIF_FLAGS.TIFF_HEADERONLY)==TIF_FLAGS.TIFF_HEADERONLY) return tif; // Setup initial directory. switch(mode[0]) { case 'r': tif.tif_nextdiroff=tif.tif_header.tiff_diroff; if(TIFFReadDirectory(tif)) { tif.tif_rawcc=0; tif.tif_flags|=TIF_FLAGS.TIFF_BUFFERSETUP; return tif; } break; case 'a': // New directories are automatically append // to the end of the directory chain when they // are written out (see TIFFWriteDirectory). if(!TIFFDefaultDirectory(tif)) goto bad; return tif; } bad: tif.tif_mode=O.RDONLY; // XXX avoid flush TIFFCleanup(tif); return null; }
public static TIFF TIFFClientOpen(string name, string mode, Stream clientdata, TIFFReadWriteProc readproc, TIFFReadWriteProc writeproc, TIFFSeekProc seekproc, TIFFCloseProc closeproc, TIFFSizeProc sizeproc) { string module = "TIFFClientOpen"; O m = TIFFgetMode(mode, module); if (m == O.ERROR) { return(null); } TIFF tif = null; try { tif = new TIFF(); } catch { TIFFErrorExt(clientdata, module, "{0}: Out of memory (TIFF structure)", name); return(null); } tif.tif_name = name; tif.tif_mode = m & ~(O.CREAT | O.TRUNC); tif.tif_curdir = 0xffff; // non-existent directory tif.tif_curoff = 0; tif.tif_curstrip = 0xffffffff; // invalid strip tif.tif_row = 0xffffffff; // read/write pre-increment tif.tif_clientdata = clientdata; if (readproc == null || writeproc == null || seekproc == null || closeproc == null || sizeproc == null) { TIFFErrorExt(clientdata, module, "One of the client procedures is NULL pointer."); return(null); } tif.tif_readproc = readproc; tif.tif_writeproc = writeproc; tif.tif_seekproc = seekproc; tif.tif_closeproc = closeproc; tif.tif_sizeproc = sizeproc; TIFFSetDefaultCompressionState(tif); // setup default state // Default is to return data MSB2LSB and enable the // use of memory-mapped files and strip chopping when // a file is opened read-only. tif.tif_flags = TIF_FLAGS.FILLORDER_MSB2LSB; #if STRIPCHOP_DEFAULT if (m == O.RDONLY || m == O.RDWR) { tif.tif_flags |= TIF_FLAGS.TIFF_STRIPCHOP; } #endif // Process library-specific flags in the open mode string. // The following flags may be used to control intrinsic library // behaviour that may or may not be desirable (usually for // compatibility with some application that claims to support // TIFF but only supports some braindead idea of what the // vendor thinks TIFF is): // // 'l' use little-endian byte order for creating a file // 'b' use big-endian byte order for creating a file // 'L' read/write information using LSB2MSB bit order // 'B' read/write information using MSB2LSB bit order // 'H' read/write information using host bit order // 'C' enable strip chopping support when reading // 'c' disable strip chopping support // 'h' read TIFF header only, do not load the first IFD // // The use of the 'l' and 'b' flags is strongly discouraged. // These flags are provided solely because numerous vendors, // typically on the PC, do not correctly support TIFF; they // only support the Intel little-endian byte order. This // support is not configured by default because it supports // the violation of the TIFF spec that says that readers *MUST* // support both byte orders. It is strongly recommended that // you not use this feature except to deal with busted apps // that write invalid TIFF. And even in those cases you should // bang on the vendors to fix their software. // // The 'L', 'B', and 'H' flags are intended for applications // that can optimize operations on data by using a particular // bit order. By default the library returns data in MSB2LSB // bit order for compatibiltiy with older versions of this // library. Returning data in the bit order of the native cpu // makes the most sense but also requires applications to check // the value of the FillOrder tag; something they probably do // not do right now. // // The 'C' and 'c' flags are provided because the library support // for chopping up large strips into multiple smaller strips is not // application-transparent and as such can cause problems. The 'c' // option permits applications that only want to look at the tags, // for example, to get the unadulterated TIFF tag information. foreach (char cp in mode) { switch (cp) { case 'b': if ((m & O.CREAT) == O.CREAT) { tif.tif_flags |= TIF_FLAGS.TIFF_SWAB; } break; case 'l': break; case 'B': tif.tif_flags = (tif.tif_flags & ~TIF_FLAGS.TIFF_FILLORDER) | TIF_FLAGS.FILLORDER_MSB2LSB; break; case 'L': tif.tif_flags = (tif.tif_flags & ~TIF_FLAGS.TIFF_FILLORDER) | TIF_FLAGS.FILLORDER_LSB2MSB; break; case 'H': tif.tif_flags = (tif.tif_flags & ~TIF_FLAGS.TIFF_FILLORDER) | HOST_FILLORDER; break; case 'C': if (m == O.RDONLY) { tif.tif_flags |= TIF_FLAGS.TIFF_STRIPCHOP; } break; case 'c': if (m == O.RDONLY) { tif.tif_flags &= ~TIF_FLAGS.TIFF_STRIPCHOP; } break; case 'h': tif.tif_flags |= TIF_FLAGS.TIFF_HEADERONLY; break; } } // Read in TIFF header. if ((tif.tif_mode & O.TRUNC) == O.TRUNC || !ReadOK(tif, tif.tif_header)) { if (tif.tif_mode == O.RDONLY) { TIFFErrorExt(tif.tif_clientdata, name, "Cannot read TIFF header"); goto bad; } // Setup header and write. tif.tif_header.tiff_magic = (tif.tif_flags & TIF_FLAGS.TIFF_SWAB) == TIF_FLAGS.TIFF_SWAB?TIFF_BIGENDIAN:TIFF_LITTLEENDIAN; tif.tif_header.tiff_version = TIFF_VERSION; if ((tif.tif_flags & TIF_FLAGS.TIFF_SWAB) == TIF_FLAGS.TIFF_SWAB) { TIFFSwab(ref tif.tif_header.tiff_version); } tif.tif_header.tiff_diroff = 0; // filled in later // The doc for "fopen" for some STD_C_LIBs says that if you // open a file for modify ("+"), then you must fseek (or // fflush?) between any freads and fwrites. This is not // necessary on most systems, but has been shown to be needed // on Solaris. TIFFSeekFile(tif, 0, SEEK.SET); if (!WriteOK(tif, tif.tif_header)) { TIFFErrorExt(tif.tif_clientdata, name, "Error writing TIFF header"); goto bad; } // Setup the byte order handling. TIFFInitOrder(tif, tif.tif_header.tiff_magic); // Setup default directory. if (!TIFFDefaultDirectory(tif)) { goto bad; } tif.tif_diroff = 0; tif.tif_dirlist.Clear(); tif.tif_dirnumber = 0; return(tif); } // Setup the byte order handling. #if MDI_SUPPORT if (tif.tif_header.tiff_magic != TIFF_BIGENDIAN && tif.tif_header.tiff_magic != TIFF_LITTLEENDIAN && tif.tif_header.tiff_magic != MDI_LITTLEENDIAN) { TIFFErrorExt(tif.tif_clientdata, name, "Not a TIFF or MDI file, bad magic number {0} (0x{1:X4})", tif.tif_header.tiff_magic, tif.tif_header.tiff_magic); goto bad; } #else if (tif.tif_header.tiff_magic != TIFF_BIGENDIAN && tif.tif_header.tiff_magic != TIFF_LITTLEENDIAN) { TIFFErrorExt(tif.tif_clientdata, name, "Not a TIFF file, bad magic number {0} (0x{1:X4})", tif.tif_header.tiff_magic, tif.tif_header.tiff_magic); goto bad; } #endif TIFFInitOrder(tif, tif.tif_header.tiff_magic); // Swap header if required. if ((tif.tif_flags & TIF_FLAGS.TIFF_SWAB) == TIF_FLAGS.TIFF_SWAB) { TIFFSwab(ref tif.tif_header.tiff_version); TIFFSwab(ref tif.tif_header.tiff_diroff); } // Now check version (if needed, it's been byte-swapped). // Note that this isn't actually a version number, it's a // magic number that doesn't change (stupid). if (tif.tif_header.tiff_version == TIFF_BIGTIFF_VERSION) { TIFFErrorExt(tif.tif_clientdata, name, "This is a BigTIFF file. This format not supported\nby this version of libtiff."); goto bad; } if (tif.tif_header.tiff_version != TIFF_VERSION) { TIFFErrorExt(tif.tif_clientdata, name, "Not a TIFF file, bad version number {0} (0x{1:X4})", tif.tif_header.tiff_version, tif.tif_header.tiff_version); goto bad; } tif.tif_flags |= TIF_FLAGS.TIFF_MYBUFFER; tif.tif_rawcp = 0; tif.tif_rawdata = null; tif.tif_rawdatasize = 0; // Sometimes we do not want to read the first directory (for example, // it may be broken) and want to proceed to other directories. I this // case we use the TIFF_HEADERONLY flag to open file and return // immediately after reading TIFF header. if ((tif.tif_flags & TIF_FLAGS.TIFF_HEADERONLY) == TIF_FLAGS.TIFF_HEADERONLY) { return(tif); } // Setup initial directory. switch (mode[0]) { case 'r': tif.tif_nextdiroff = tif.tif_header.tiff_diroff; if (TIFFReadDirectory(tif)) { tif.tif_rawcc = 0; tif.tif_flags |= TIF_FLAGS.TIFF_BUFFERSETUP; return(tif); } break; case 'a': // New directories are automatically append // to the end of the directory chain when they // are written out (see TIFFWriteDirectory). if (!TIFFDefaultDirectory(tif)) { goto bad; } return(tif); } bad: tif.tif_mode = O.RDONLY; // XXX avoid flush TIFFCleanup(tif); return(null); }