// Return size of TIFFDataType in bytes public static int TIFFDataWidth(TIFFDataType type) { switch (type) { case TIFFDataType.TIFF_NOTYPE: case TIFFDataType.TIFF_BYTE: case TIFFDataType.TIFF_ASCII: case TIFFDataType.TIFF_SBYTE: case TIFFDataType.TIFF_UNDEFINED: return(1); case TIFFDataType.TIFF_SHORT: case TIFFDataType.TIFF_SSHORT: return(2); case TIFFDataType.TIFF_LONG: case TIFFDataType.TIFF_SLONG: case TIFFDataType.TIFF_FLOAT: case TIFFDataType.TIFF_IFD: return(4); case TIFFDataType.TIFF_RATIONAL: case TIFFDataType.TIFF_SRATIONAL: case TIFFDataType.TIFF_DOUBLE: return(8); default: return(0); // will return 0 for unknown types } }
static TIFFFieldInfo TIFFFindFieldInfo(TIFF tif, TIFFTAG tag, TIFFDataType dt) { if (tif.tif_foundfield != null && tif.tif_foundfield.field_tag == tag && (dt == TIFFDataType.TIFF_ANY || dt == tif.tif_foundfield.field_type)) { return(tif.tif_foundfield); } // If we are invoked with no field information, then just return. if (tif.tif_fieldinfo == null || tif.tif_fieldinfo.Count == 0) { return(null); } #if !USE_TIFFFindFieldInfoSearch foreach (TIFFFieldInfo fip in tif.tif_fieldinfo) { if (fip.field_tag == tag && (dt == TIFFDataType.TIFF_ANY || fip.field_type == dt)) { return(tif.tif_foundfield = fip); } } return(null); #else return(TIFFFindFieldInfoSearch(tif, tag, dt, 0, tif.tif_fieldinfo.Count)); #endif }
public string field_name; // ASCII name public TIFFFieldInfo(TIFFTAG field_tag, short field_readcount, short field_writecount, TIFFDataType field_type, FIELD field_bit, bool field_oktochange, bool field_passcount, string field_name) { this.field_tag = field_tag; this.field_readcount = field_readcount; this.field_writecount = field_writecount; this.field_type = field_type; this.field_bit = field_bit; this.field_oktochange = field_oktochange; this.field_passcount = field_passcount; this.field_name = field_name; }
static TIFFFieldInfo TIFFCreateAnonFieldInfo(TIFF tif, TIFFTAG tag, TIFFDataType field_type) { try { // ??? TIFFFieldInfo fld=new TIFFFieldInfo(tag, TIFF_VARIABLE2, TIFF_VARIABLE2, field_type, FIELD.CUSTOM, true, true, "Tag "+tag); TIFFFieldInfo fld = new TIFFFieldInfo(tag, TIFF_VARIABLE, TIFF_VARIABLE, field_type, FIELD.CUSTOM, true, true, "Tag " + tag); return(fld); } catch { return(null); } }
static TIFFFieldInfo TIFFFindOrRegisterFieldInfo(TIFF tif, TIFFTAG tag, TIFFDataType dt) { TIFFFieldInfo fld = TIFFFindFieldInfo(tif, tag, dt); if (fld == null) { fld = TIFFCreateAnonFieldInfo(tif, tag, dt); if (!_TIFFMergeFieldInfo(tif, fld)) { return(null); } } return(fld); }
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); }
static bool ZIPVSetField(TIFF tif, TIFFTAG tag, TIFFDataType dt, object[] ap) { ZIPState sp = tif.tif_data as ZIPState; string module = "ZIPVSetField"; switch (tag) { case TIFFTAG.ZIPQUALITY: sp.zipquality = __GetAsInt(ap, 0); if ((sp.state & ZSTATE.INIT_ENCODE) == ZSTATE.INIT_ENCODE) { if (zlib.deflateParams(sp.stream, sp.zipquality, zlib.Z_DEFAULT_STRATEGY) != zlib.Z_OK) { TIFFErrorExt(tif.tif_clientdata, module, "{0}: zlib error: {1}", tif.tif_name, sp.stream.msg); return(false); } } return(true); default: return(sp.vsetparent(tif, tag, dt, ap)); } //NOTREACHED }
static TIFFFieldInfo TIFFFindFieldInfoByName(TIFF tif, string field_name, TIFFDataType dt) { if (tif.tif_foundfield != null && tif.tif_foundfield.field_name == field_name && (dt == TIFFDataType.TIFF_ANY || dt == tif.tif_foundfield.field_type)) { return(tif.tif_foundfield); } // If we are invoked with no field information, then just return. if (tif.tif_fieldinfo == null || tif.tif_fieldinfo.Count == 0) { return(null); } foreach (TIFFFieldInfo fip in tif.tif_fieldinfo) { if (fip.field_name == field_name && (dt == TIFFDataType.TIFF_ANY || fip.field_type == dt)) { return(tif.tif_foundfield = fip); } } return(null); }
// Return size of TIFFDataType in bytes. // // XXX: We need a separate function to determine the space needed // to store the value. For TIFF_RATIONAL values TIFFDataWidth() returns 8, // but we use 4-byte float to represent rationals. static int TIFFDataSize(TIFFDataType type) { switch (type) { case TIFFDataType.TIFF_BYTE: case TIFFDataType.TIFF_ASCII: case TIFFDataType.TIFF_SBYTE: case TIFFDataType.TIFF_UNDEFINED: return(1); case TIFFDataType.TIFF_SHORT: case TIFFDataType.TIFF_SSHORT: return(2); case TIFFDataType.TIFF_LONG: case TIFFDataType.TIFF_SLONG: case TIFFDataType.TIFF_FLOAT: case TIFFDataType.TIFF_IFD: case TIFFDataType.TIFF_RATIONAL: case TIFFDataType.TIFF_SRATIONAL: return(4); case TIFFDataType.TIFF_DOUBLE: return(8); default: return(0); } }
static TIFFFieldInfo TIFFFindFieldInfoSearch(TIFF tif, TIFFTAG tag, TIFFDataType dt, int min, int num) { if (num == 0) { return(null); } TIFFFieldInfo fip = tif.tif_fieldinfo[min + num / 2]; if (fip.field_tag == tag) { int pos = min + num / 2; if (dt == TIFFDataType.TIFF_ANY) { for (; ;) // Find first { if (pos == 0) { break; } if (tif.tif_fieldinfo[pos - 1].field_tag != tag) { break; } pos--; fip = tif.tif_fieldinfo[pos]; } return(tif.tif_foundfield = fip); } if (fip.field_type == dt) { return(tif.tif_foundfield = fip); } //if(fip.field_type>dt) return TIFFFindFieldInfoSearch(tif, tag, dt, min, num/2); //return TIFFFindFieldInfoSearch(tif, tag, dt, min+num/2+1, num-(num/2+1)); for (; ;) // preceding fieldinfos and exit if found DataType { if (pos == 0) { break; } if (tif.tif_fieldinfo[pos - 1].field_tag != tag) { break; } pos--; fip = tif.tif_fieldinfo[pos]; if (fip.field_type == dt) { return(tif.tif_foundfield = fip); } } pos = min + num / 2; for (; ;) // succeding fieldinfos first and exit if found DataType { if (pos == (tif.tif_fieldinfo.Count - 1)) { break; } if (tif.tif_fieldinfo[pos + 1].field_tag != tag) { break; } pos++; fip = tif.tif_fieldinfo[pos]; if (fip.field_type == dt) { return(tif.tif_foundfield = fip); } } return(null); } if (fip.field_tag > tag) { return(TIFFFindFieldInfoSearch(tif, tag, dt, min, num / 2)); } return(TIFFFindFieldInfoSearch(tif, tag, dt, min + num / 2 + 1, num - (num / 2 + 1))); }
static bool _TIFFVSetField(TIFF tif, TIFFTAG tag, TIFFDataType dt, object[] ap) { string module="_TIFFVSetField"; TIFFDirectory td=tif.tif_dir; bool status=true; uint v; switch(tag) { case TIFFTAG.SUBFILETYPE: td.td_subfiletype=(FILETYPE)__GetAsUint(ap, 0); break; case TIFFTAG.IMAGEWIDTH: td.td_imagewidth=__GetAsUint(ap, 0); break; case TIFFTAG.IMAGELENGTH: td.td_imagelength=__GetAsUint(ap, 0); break; case TIFFTAG.BITSPERSAMPLE: td.td_bitspersample=__GetAsUshort(ap, 0); // If the data require post-decoding processing to byte-swap // samples, set it up here. Note that since tags are required // to be ordered, compression code can override this behaviour // in the setup method if it wants to roll the post decoding // work in with its normal work. if((tif.tif_flags&TIF_FLAGS.TIFF_SWAB)!=0) { if(td.td_bitspersample==16) tif.tif_postdecode=TIFFSwab16BitData; else if(td.td_bitspersample==24) tif.tif_postdecode=TIFFSwab24BitData; else if(td.td_bitspersample==32) tif.tif_postdecode=TIFFSwab32BitData; else if(td.td_bitspersample==64) tif.tif_postdecode=TIFFSwab64BitData; else if(td.td_bitspersample==128) tif.tif_postdecode=TIFFSwab64BitData; // two 64's } break; case TIFFTAG.COMPRESSION: v=__GetAsUint(ap, 0)&0xffff; // If we're changing the compression scheme, the notify the // previous module so that it can cleanup any state it's setup. if(TIFFFieldSet(tif, FIELD.COMPRESSION)) { if(td.td_compression==(COMPRESSION)v) break; tif.tif_cleanup(tif); tif.tif_flags&=~TIF_FLAGS.TIFF_CODERSETUP; } // Setup new compression routine state. if(status=TIFFSetCompressionScheme(tif, (COMPRESSION)v)) td.td_compression=(COMPRESSION)v; else status=false; break; case TIFFTAG.PHOTOMETRIC: td.td_photometric=(PHOTOMETRIC)__GetAsUshort(ap, 0); break; case TIFFTAG.THRESHHOLDING: td.td_threshholding=(THRESHHOLD)__GetAsUshort(ap, 0); break; case TIFFTAG.FILLORDER: v=__GetAsUint(ap, 0); if((FILLORDER)v!=FILLORDER.LSB2MSB&&(FILLORDER)v!=FILLORDER.MSB2LSB) goto badvalue; td.td_fillorder=(FILLORDER)v; break; case TIFFTAG.ORIENTATION: v=__GetAsUint(ap, 0); if((ORIENTATION)v<ORIENTATION.TOPLEFT||ORIENTATION.LEFTBOT<(ORIENTATION)v) goto badvalue; td.td_orientation=(ORIENTATION)v; break; case TIFFTAG.SAMPLESPERPIXEL: // XXX should cross check -- e.g. if pallette, then 1 v=__GetAsUint(ap, 0); if(v==0) goto badvalue; td.td_samplesperpixel=(ushort)v; break; case TIFFTAG.ROWSPERSTRIP: v=__GetAsUint(ap, 0); if(v==0) goto badvalue; td.td_rowsperstrip=v; if(!TIFFFieldSet(tif, FIELD.TILEDIMENSIONS)) { td.td_tilelength=v; td.td_tilewidth=td.td_imagewidth; } break; case TIFFTAG.MINSAMPLEVALUE: td.td_minsamplevalue=__GetAsUshort(ap, 0); break; case TIFFTAG.MAXSAMPLEVALUE: td.td_maxsamplevalue=__GetAsUshort(ap, 0); break; case TIFFTAG.SMINSAMPLEVALUE: td.td_sminsamplevalue=__GetAsDouble(ap, 0); break; case TIFFTAG.SMAXSAMPLEVALUE: td.td_smaxsamplevalue=__GetAsDouble(ap, 0); break; case TIFFTAG.XRESOLUTION: td.td_xresolution=__GetAsDouble(ap, 0); break; case TIFFTAG.YRESOLUTION: td.td_yresolution=__GetAsDouble(ap, 0); break; case TIFFTAG.PLANARCONFIG: v=__GetAsUint(ap, 0); if((PLANARCONFIG)v!=PLANARCONFIG.CONTIG&&(PLANARCONFIG)v!=PLANARCONFIG.SEPARATE) goto badvalue; td.td_planarconfig=(PLANARCONFIG)v; break; case TIFFTAG.XPOSITION: td.td_xposition=__GetAsDouble(ap, 0); break; case TIFFTAG.YPOSITION: td.td_yposition=__GetAsDouble(ap, 0); break; case TIFFTAG.RESOLUTIONUNIT: v=__GetAsUint(ap, 0); if((RESUNIT)v<RESUNIT.NONE||RESUNIT.CENTIMETER<(RESUNIT)v) goto badvalue; td.td_resolutionunit=(RESUNIT)v; break; case TIFFTAG.PAGENUMBER: td.td_pagenumber[0]=__GetAsUshort(ap, 0); td.td_pagenumber[1]=__GetAsUshort(ap, 1); break; case TIFFTAG.HALFTONEHINTS: td.td_halftonehints[0]=__GetAsUshort(ap, 0); td.td_halftonehints[1]=__GetAsUshort(ap, 1); break; case TIFFTAG.COLORMAP: v=1u<<td.td_bitspersample; TIFFsetShortArray(ref td.td_colormap[0], (ushort[])ap[0], v); TIFFsetShortArray(ref td.td_colormap[1], (ushort[])ap[1], v); TIFFsetShortArray(ref td.td_colormap[2], (ushort[])ap[2], v); break; case TIFFTAG.EXTRASAMPLES: if(!setExtraSamples(td, ap, out v)) goto badvalue; break; case TIFFTAG.MATTEING: td.td_extrasamples=(ushort)((__GetAsInt(ap, 0)!=0)?1:0); if(td.td_extrasamples!=0) { ushort[] sv=new ushort[] { (ushort)EXTRASAMPLE.ASSOCALPHA }; TIFFsetShortArray(ref td.td_sampleinfo, sv, 1); } break; case TIFFTAG.TILEWIDTH: v=__GetAsUint(ap, 0); if((v%16)!=0) { if(tif.tif_mode!=O.RDONLY) goto badvalue; TIFFWarningExt(tif.tif_clientdata, tif.tif_name, "Nonstandard tile width {0}, convert file", v); } td.td_tilewidth=v; tif.tif_flags|=TIF_FLAGS.TIFF_ISTILED; break; case TIFFTAG.TILELENGTH: v=__GetAsUint(ap, 0); if((v%16)!=0) { if(tif.tif_mode!=O.RDONLY) goto badvalue; TIFFWarningExt(tif.tif_clientdata, tif.tif_name, "Nonstandard tile length {0}, convert file", v); } td.td_tilelength=v; tif.tif_flags|=TIF_FLAGS.TIFF_ISTILED; break; case TIFFTAG.TILEDEPTH: v=__GetAsUint(ap, 0); if(v==0) goto badvalue; td.td_tiledepth=v; break; case TIFFTAG.DATATYPE: v=__GetAsUint(ap, 0); switch(v) { case DATATYPE_VOID: td.td_sampleformat=SAMPLEFORMAT.VOID; break; case DATATYPE_INT: td.td_sampleformat=SAMPLEFORMAT.INT; break; case DATATYPE_UINT: td.td_sampleformat=SAMPLEFORMAT.UINT; break; case DATATYPE_IEEEFP: td.td_sampleformat=SAMPLEFORMAT.IEEEFP; break; default: goto badvalue; } break; case TIFFTAG.SAMPLEFORMAT: v=__GetAsUint(ap, 0); if((SAMPLEFORMAT)v<SAMPLEFORMAT.UINT||SAMPLEFORMAT.COMPLEXIEEEFP<(SAMPLEFORMAT)v) goto badvalue; td.td_sampleformat=(SAMPLEFORMAT)v; // Try to fix up the SWAB function for complex data. if(td.td_sampleformat==SAMPLEFORMAT.COMPLEXINT&&td.td_bitspersample==32&&tif.tif_postdecode==TIFFSwab32BitData) tif.tif_postdecode=TIFFSwab16BitData; else if((td.td_sampleformat==SAMPLEFORMAT.COMPLEXINT||td.td_sampleformat==SAMPLEFORMAT.COMPLEXIEEEFP)&&td.td_bitspersample==64&& tif.tif_postdecode==TIFFSwab64BitData) tif.tif_postdecode=TIFFSwab32BitData; break; case TIFFTAG.IMAGEDEPTH: td.td_imagedepth=__GetAsUint(ap, 0); break; case TIFFTAG.SUBIFD: if((tif.tif_flags&TIF_FLAGS.TIFF_INSUBIFD)==0) { td.td_nsubifd=__GetAsUshort(ap, 0); uint[] tmp=new uint[1]; tmp[0]=(uint)ap[1]; TIFFsetLongArray(ref td.td_subifd, tmp, td.td_nsubifd); } else { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Sorry, cannot nest SubIFDs", tif.tif_name); status=false; } break; case TIFFTAG.YCBCRPOSITIONING: td.td_ycbcrpositioning=(YCBCRPOSITION)__GetAsUshort(ap, 0); break; case TIFFTAG.YCBCRSUBSAMPLING: td.td_ycbcrsubsampling[0]=__GetAsUshort(ap, 0); td.td_ycbcrsubsampling[1]=__GetAsUshort(ap, 1); break; case TIFFTAG.TRANSFERFUNCTION: v=(uint)((td.td_samplesperpixel-td.td_extrasamples)>1?3:1); for(int i=0; i<v; i++) TIFFsetShortArray(ref td.td_transferfunction[i], (ushort[])ap[i], 1u<<td.td_bitspersample); break; case TIFFTAG.REFERENCEBLACKWHITE: // XXX should check for null range TIFFsetDoubleArray(ref td.td_refblackwhite, (double[])ap[0], 6); break; case TIFFTAG.INKNAMES: v=__GetAsUint(ap, 0); string s=(string)ap[1]; v=checkInkNamesString(tif, v, s); status=v>0; if(v>0) { td.td_inknames=s.Substring(0, (int)v); td.td_inknameslen=(int)v; } break; default: { TIFFFieldInfo fip=TIFFFindFieldInfo(tif, tag, dt); // was TIFFDataType.TIFF_ANY); TIFFTagValue tv; int iCustom; // This can happen if multiple images are open with different // codecs which have private tags. The global tag information // table may then have tags that are valid for one file but not // the other. If the client tries to set a tag that is not valid // for the image's codec then we'll arrive here. This // happens, for example, when tiffcp is used to convert between // compression schemes and codec-specific tags are blindly copied. if(fip==null||fip.field_bit!=FIELD.CUSTOM) { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Invalid {1}tag \"{2}\" (not supported by codec)", tif.tif_name, isPseudoTag(tag)?"pseudo-":"", fip!=null?fip.field_name:"Unknown"); status=false; break; } // Find the existing entry for this custom value. tv=null; for(iCustom=0; iCustom<td.td_customValueCount; iCustom++) { if(td.td_customValues[iCustom].info.field_tag==tag) { tv=td.td_customValues[iCustom]; tv.value=null; break; } } // Grow the custom list if the entry was not found. if(tv==null) { try { td.td_customValueCount++; if(td.td_customValues==null) td.td_customValues=new List<TIFFTagValue>(); tv=new TIFFTagValue(); tv.info=fip; td.td_customValues.Add(tv); } catch { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Failed to allocate space for list of custom values", tif.tif_name); status=false; goto end; } } // Set custom value ... save a copy of the custom tag value. if(TIFFDataSize(fip.field_type)==0) { status=false; TIFFErrorExt(tif.tif_clientdata, module, "{0}: Bad field type {1} for \"{2}\"", tif.tif_name, fip.field_type, fip.field_name); goto end; } int apcount=0; if(fip.field_passcount) tv.count=__GetAsInt(ap, apcount++); else if(fip.field_writecount==TIFF_VARIABLE) tv.count=1; else if(fip.field_writecount==TIFF_SPP) tv.count=td.td_samplesperpixel; else tv.count=fip.field_writecount; if(fip.field_type==TIFFDataType.TIFF_ASCII) tv.value=(string)ap[apcount++]; else { if(tv.count<1) { status=false; goto end; } byte[] byteArray=null; sbyte[] sbyteArray=null; ushort[] ushortArray=null; short[] shortArray=null; uint[] uintArray=null; int[] intArray=null; float[] floatArray=null; double[] doubleArray=null; try { switch(fip.field_type) { case TIFFDataType.TIFF_UNDEFINED: case TIFFDataType.TIFF_BYTE: tv.value=byteArray=new byte[tv.count]; break; case TIFFDataType.TIFF_SBYTE: tv.value=sbyteArray=new sbyte[tv.count]; break; case TIFFDataType.TIFF_SHORT: tv.value=ushortArray=new ushort[tv.count]; break; case TIFFDataType.TIFF_SSHORT: tv.value=shortArray=new short[tv.count]; break; case TIFFDataType.TIFF_IFD: case TIFFDataType.TIFF_LONG: tv.value=uintArray=new uint[tv.count]; break; case TIFFDataType.TIFF_SLONG: tv.value=intArray=new int[tv.count]; break; case TIFFDataType.TIFF_FLOAT: tv.value=floatArray=new float[tv.count]; break; case TIFFDataType.TIFF_RATIONAL: case TIFFDataType.TIFF_SRATIONAL: case TIFFDataType.TIFF_DOUBLE: tv.value=doubleArray=new double[tv.count]; break; default: tv.value=null; break; } } catch { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Out of memory.", tif.tif_name); status=false; goto end; } bool done=false; if((fip.field_passcount||fip.field_writecount==TIFF_VARIABLE||fip.field_writecount==TIFF_SPP)) { Array a=ap[apcount] as Array; if(a!=null&&a.Length>=tv.count) { switch(fip.field_type) { case TIFFDataType.TIFF_UNDEFINED: case TIFFDataType.TIFF_BYTE: if(a is byte[]) { Array.Copy(a, byteArray, tv.count); done=true; } else { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Bad argument type for \"{2}\" ({1}). Should be a byte[].", tif.tif_name, fip.field_type, fip.field_name); status=false; goto end; } break; case TIFFDataType.TIFF_SBYTE: if(a is sbyte[]) { Array.Copy(a, sbyteArray, tv.count); done=true; } else { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Bad argument type for \"{2}\" ({1}). Should be a sbyte[].", tif.tif_name, fip.field_type, fip.field_name); status=false; goto end; } break; case TIFFDataType.TIFF_SHORT: if(a is ushort[]) { Array.Copy(a, ushortArray, tv.count); done=true; } else { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Bad argument type for \"{2}\" ({1}). Should be a ushort[].", tif.tif_name, fip.field_type, fip.field_name); status=false; goto end; } break; case TIFFDataType.TIFF_SSHORT: if(a is short[]) { Array.Copy(a, shortArray, tv.count); done=true; } else { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Bad argument type for \"{2}\" ({1}). Should be a short[].", tif.tif_name, fip.field_type, fip.field_name); status=false; goto end; } break; case TIFFDataType.TIFF_IFD: case TIFFDataType.TIFF_LONG: if(a is uint[]) { Array.Copy(a, uintArray, tv.count); done=true; } else { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Bad argument type for \"{2}\" ({1}). Should be a ulong[].", tif.tif_name, fip.field_type, fip.field_name); status=false; goto end; } break; case TIFFDataType.TIFF_SLONG: if(a is int[]) { Array.Copy(a, intArray, tv.count); done=true; } else { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Bad argument type for \"{2}\" ({1}). Should be a long[].", tif.tif_name, fip.field_type, fip.field_name); status=false; goto end; } break; case TIFFDataType.TIFF_FLOAT: if(a is float[]) { Array.Copy(a, floatArray, tv.count); done=true; } else { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Bad argument type for \"{2}\" ({1}). Should be a float[].", tif.tif_name, fip.field_type, fip.field_name); status=false; goto end; } break; case TIFFDataType.TIFF_RATIONAL: case TIFFDataType.TIFF_SRATIONAL: case TIFFDataType.TIFF_DOUBLE: if(a is double[]) { Array.Copy(a, doubleArray, tv.count); done=true; } else { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Bad argument type for \"{2}\" ({1}). Should be a double[].", tif.tif_name, fip.field_type, fip.field_name); status=false; goto end; } break; default: tv.value=null; break; } // switch } // if(a!=null&&a.Length>=tv.count) else if(a!=null) { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Bad argument type for \"{2}\" ({1}). Array has too few elements.", tif.tif_name, fip.field_type, fip.field_name); status=false; goto end; } } if(!done) { try { Array a=ap[apcount] as Array; if(a!=null&&a.Length>=tv.count) { switch(fip.field_type) { case TIFFDataType.TIFF_UNDEFINED: case TIFFDataType.TIFF_BYTE: if(a is byte[]) { Array.Copy(a, byteArray, tv.count); done=true; } else { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Bad argument type for \"{2}\" ({1}). Should be a byte[].", tif.tif_name, fip.field_type, fip.field_name); status=false; goto end; } break; case TIFFDataType.TIFF_SBYTE: if(a is sbyte[]) { Array.Copy(a, sbyteArray, tv.count); done=true; } else { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Bad argument type for \"{2}\" ({1}). Should be a sbyte[].", tif.tif_name, fip.field_type, fip.field_name); status=false; goto end; } break; case TIFFDataType.TIFF_SHORT: if(a is ushort[]) { Array.Copy(a, ushortArray, tv.count); done=true; } else { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Bad argument type for \"{2}\" ({1}). Should be a ushort[].", tif.tif_name, fip.field_type, fip.field_name); status=false; goto end; } break; case TIFFDataType.TIFF_SSHORT: if(a is short[]) { Array.Copy(a, shortArray, tv.count); done=true; } else { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Bad argument type for \"{2}\" ({1}). Should be a short[].", tif.tif_name, fip.field_type, fip.field_name); status=false; goto end; } break; case TIFFDataType.TIFF_IFD: case TIFFDataType.TIFF_LONG: if(a is uint[]) { Array.Copy(a, uintArray, tv.count); done=true; } else { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Bad argument type for \"{2}\" ({1}). Should be a ulong[].", tif.tif_name, fip.field_type, fip.field_name); status=false; goto end; } break; case TIFFDataType.TIFF_SLONG: if(a is int[]) { Array.Copy(a, intArray, tv.count); done=true; } else { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Bad argument type for \"{2}\" ({1}). Should be a long[].", tif.tif_name, fip.field_type, fip.field_name); status=false; goto end; } break; case TIFFDataType.TIFF_FLOAT: if(a is float[]) { Array.Copy(a, floatArray, tv.count); done=true; } else { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Bad argument type for \"{2}\" ({1}). Should be a float[].", tif.tif_name, fip.field_type, fip.field_name); status=false; goto end; } break; case TIFFDataType.TIFF_RATIONAL: case TIFFDataType.TIFF_SRATIONAL: case TIFFDataType.TIFF_DOUBLE: if(a is double[]) { Array.Copy(a, doubleArray, tv.count); done=true; } else { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Bad argument type for \"{2}\" ({1}). Should be a double[].", tif.tif_name, fip.field_type, fip.field_name); status=false; goto end; } break; default: tv.value=null; break; } // switch } else { switch(fip.field_type) { case TIFFDataType.TIFF_UNDEFINED: case TIFFDataType.TIFF_BYTE: for(int i=0; i<tv.count; i++) byteArray[i]=__GetAsByte(ap, apcount++); break; case TIFFDataType.TIFF_SBYTE: for(int i=0; i<tv.count; i++) sbyteArray[i]=__GetAsSbyte(ap, apcount++); break; case TIFFDataType.TIFF_SHORT: for(int i=0; i<tv.count; i++) ushortArray[i]=__GetAsUshort(ap, apcount++); break; case TIFFDataType.TIFF_SSHORT: for(int i=0; i<tv.count; i++) shortArray[i]=__GetAsShort(ap, apcount++); break; case TIFFDataType.TIFF_IFD: case TIFFDataType.TIFF_LONG: for(int i=0; i<tv.count; i++) uintArray[i]=__GetAsUint(ap, apcount++); break; case TIFFDataType.TIFF_SLONG: for(int i=0; i<tv.count; i++) intArray[i]=__GetAsInt(ap, apcount++); break; case TIFFDataType.TIFF_FLOAT: for(int i=0; i<tv.count; i++) floatArray[i]=__GetAsFloat(ap, apcount++); break; case TIFFDataType.TIFF_RATIONAL: case TIFFDataType.TIFF_SRATIONAL: case TIFFDataType.TIFF_DOUBLE: for(int i=0; i<tv.count; i++) doubleArray[i]=__GetAsDouble(ap, apcount++); break; } } } catch { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Bad argument({3}) type for \"{2}\" ({1}). Should be an Array anyway!", tif.tif_name, fip.field_type, fip.field_name, apcount); status=false; goto end; } } // if(!done) } // fip.field_type!=TIFFDataType.TIFF_ASCII } // default: break; } // switch() if(status) { TIFFSetFieldBit(tif, TIFFFieldWithTag(tif, tag).field_bit); tif.tif_flags|=TIF_FLAGS.TIFF_DIRTYDIRECT; } end: return status; badvalue: TIFFErrorExt(tif.tif_clientdata, module, "{0}: Bad value {1} for \"{2}\" tag", tif.tif_name, v, TIFFFieldWithTag(tif, tag).field_name); return false; }
public static bool TIFFVSetField(TIFF tif, TIFFTAG tag, TIFFDataType dt, object[] ap) { return OkToChangeTag(tif, tag)?tif.tif_tagmethods.vsetfield(tif, tag, dt, ap):false; }
public static bool TIFFSetField(TIFF tif, TIFFTAG tag, TIFFDataType dt, params object[] ap) { return TIFFVSetField(tif, tag, dt, ap); }
static bool ZIPVSetField(TIFF tif, TIFFTAG tag, TIFFDataType dt, object[] ap) { ZIPState sp=tif.tif_data as ZIPState; string module="ZIPVSetField"; switch(tag) { case TIFFTAG.ZIPQUALITY: sp.zipquality=__GetAsInt(ap, 0); if((sp.state&ZSTATE.INIT_ENCODE)==ZSTATE.INIT_ENCODE) { if(zlib.deflateParams(sp.stream, sp.zipquality, zlib.Z_DEFAULT_STRATEGY)!=zlib.Z_OK) { TIFFErrorExt(tif.tif_clientdata, module, "{0}: zlib error: {1}", tif.tif_name, sp.stream.msg); return false; } } return true; default: return sp.vsetparent(tif, tag, dt, ap); } //NOTREACHED }
// Write an array of "type" values for a specified tag (i.e. this is a tag // which is allowed to have different types, e.g. SMaxSampleType). // Internally the data values are represented as double since a double can // hold any of the TIFF tag types (yes, this should really be an abstract // type tany_t for portability). The data is converted into the specified // type in a temporary buffer and then handed off to the appropriate array // writer. static bool TIFFWriteAnyArray(TIFF tif, TIFFDataType type, TIFFTAG tag, TIFFDirEntry dir, uint n, double[] v) { dir.tdir_tag=(ushort)tag; dir.tdir_type=(ushort)type; dir.tdir_count=n; switch(type) { case TIFFDataType.TIFF_BYTE: { byte[] bp=null; try { bp=new byte[n]; } catch { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "No space to write array"); return false; } for(uint i=0; i<n; i++) bp[i]=(byte)v[i]; return TIFFWriteByteArray(tif, dir, bp); } case TIFFDataType.TIFF_SBYTE: { sbyte[] bp=null; try { bp=new sbyte[n]; } catch { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "No space to write array"); return false; } for(uint i=0; i<n; i++) bp[i]=(sbyte)v[i]; return TIFFWriteByteArray(tif, dir, bp); } case TIFFDataType.TIFF_SHORT: { ushort[] bp=null; try { bp=new ushort[n]; } catch { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "No space to write array"); return false; } for(uint i=0; i<n; i++) bp[i]=(ushort)v[i]; return TIFFWriteShortArray(tif, dir, bp); } case TIFFDataType.TIFF_SSHORT: { short[] bp=null; try { bp=new short[n]; } catch { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "No space to write array"); return false; } for(uint i=0; i<n; i++) bp[i]=(short)v[i]; return TIFFWriteShortArray(tif, dir, bp); } case TIFFDataType.TIFF_LONG: { uint[] bp=null; try { bp=new uint[n]; } catch { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "No space to write array"); return false; } for(uint i=0; i<n; i++) bp[i]=(uint)v[i]; return TIFFWriteLongArray(tif, dir, bp); } case TIFFDataType.TIFF_SLONG: { int[] bp=null; try { bp=new int[n]; } catch { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "No space to write array"); return false; } for(uint i=0; i<n; i++) bp[i]=(int)v[i]; return TIFFWriteLongArray(tif, dir, bp); } case TIFFDataType.TIFF_FLOAT: { float[] bp=null; try { bp=new float[n]; } catch { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "No space to write array"); return false; } for(uint i=0; i<n; i++) bp[i]=(float)v[i]; return TIFFWriteFloatArray(tif, dir, bp); } case TIFFDataType.TIFF_DOUBLE: return TIFFWriteDoubleArray(tif, dir, v); default: // TIFF_NOTYPE // TIFF_ASCII // TIFF_UNDEFINED // TIFF_RATIONAL // TIFF_SRATIONAL return false; } }
static bool JPEGVSetField(TIFF tif, TIFFTAG tag, TIFFDataType dt, object[] ap) { JPEGState sp=tif.tif_data as JPEGState; TIFFDirectory td=tif.tif_dir; #if DEBUG if(sp==null) throw new Exception("sp==null"); #endif switch(tag) { case TIFFTAG.JPEGTABLES: uint v32=__GetAsUint(ap, 0); if(v32==0) return false;// XXX TIFFsetByteArray(ref sp.jpegtables, ap[1] as byte[], v32); sp.jpegtables_length=v32; TIFFSetFieldBit(tif, FIELD.JPEG_JPEGTABLES); break; case TIFFTAG.JPEGQUALITY: sp.jpegquality=__GetAsInt(ap, 0); return true; // pseudo tag case TIFFTAG.JPEGCOLORMODE: sp.jpegcolormode=(JPEGCOLORMODE)__GetAsInt(ap, 0); JPEGResetUpsampled(tif); return true; // pseudo tag case TIFFTAG.JPEGTABLESMODE: sp.jpegtablesmode=(JPEGTABLESMODE)__GetAsInt(ap, 0); return true; // pseudo tag case TIFFTAG.PHOTOMETRIC: bool ret_value=sp.vsetparent(tif, tag, dt, ap); JPEGResetUpsampled(tif); return ret_value; case TIFFTAG.YCBCRSUBSAMPLING: // mark the fact that we have a real ycbcrsubsampling! sp.ycbcrsampling_fetched=true; // should we be recomputing upsampling info here? return sp.vsetparent(tif, tag, dt, ap); case TIFFTAG.FAXRECVPARAMS: sp.recvparams=__GetAsUint(ap, 0); break; case TIFFTAG.FAXSUBADDRESS: sp.subaddress=ap[0] as string; break; case TIFFTAG.FAXRECVTIME: sp.recvtime=__GetAsUint(ap, 0); break; case TIFFTAG.FAXDCS: sp.faxdcs=ap[0] as string; break; default: return sp.vsetparent(tif, tag, dt, ap); } TIFFFieldInfo fip=TIFFFieldWithTag(tif, tag); if(fip!=null) TIFFSetFieldBit(tif, fip.field_bit); else return false; tif.tif_flags|=TIF_FLAGS.TIFF_DIRTYDIRECT; return true; }
static TIFFFieldInfo TIFFCreateAnonFieldInfo(TIFF tif, TIFFTAG tag, TIFFDataType field_type) { try { // ??? TIFFFieldInfo fld=new TIFFFieldInfo(tag, TIFF_VARIABLE2, TIFF_VARIABLE2, field_type, FIELD.CUSTOM, true, true, "Tag "+tag); TIFFFieldInfo fld=new TIFFFieldInfo(tag, TIFF_VARIABLE, TIFF_VARIABLE, field_type, FIELD.CUSTOM, true, true, "Tag "+tag); return fld; } catch { return null; } }
static TIFFFieldInfo TIFFFindOrRegisterFieldInfo(TIFF tif, TIFFTAG tag, TIFFDataType dt) { TIFFFieldInfo fld=TIFFFindFieldInfo(tif, tag, dt); if(fld==null) { fld=TIFFCreateAnonFieldInfo(tif, tag, dt); if(!_TIFFMergeFieldInfo(tif, fld)) return null; } return fld; }
// Setup a directory entry that references a samples/pixel array of "type" // values and (potentially) write the associated indirect values. The source // data from TIFFGetField() for the specified tag must be returned as double. static bool TIFFWritePerSampleAnys(TIFF tif, TIFFDataType type, TIFFTAG tag, TIFFDirEntry dir) { ushort samples=tif.tif_dir.td_samplesperpixel; double[] w=null; object[] ap=null; try { w=new double[samples]; ap=new object[samples]; } catch { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "No space to write per-sample shorts"); return false; } TIFFGetField(tif, tag, ap); for(int i=0; i<samples; i++) w[i]=__GetAsDouble(ap, i); return TIFFWriteAnyArray(tif, type, tag, dir, samples, w); }
static TIFFFieldInfo TIFFFindFieldInfoSearch(TIFF tif, TIFFTAG tag, TIFFDataType dt, int min, int num) { if(num==0) return null; TIFFFieldInfo fip=tif.tif_fieldinfo[min+num/2]; if(fip.field_tag==tag) { int pos=min+num/2; if(dt==TIFFDataType.TIFF_ANY) { for(; ; ) // Find first { if(pos==0) break; if(tif.tif_fieldinfo[pos-1].field_tag!=tag) break; pos--; fip=tif.tif_fieldinfo[pos]; } return tif.tif_foundfield=fip; } if(fip.field_type==dt) return tif.tif_foundfield=fip; //if(fip.field_type>dt) return TIFFFindFieldInfoSearch(tif, tag, dt, min, num/2); //return TIFFFindFieldInfoSearch(tif, tag, dt, min+num/2+1, num-(num/2+1)); for(; ; ) // preceding fieldinfos and exit if found DataType { if(pos==0) break; if(tif.tif_fieldinfo[pos-1].field_tag!=tag) break; pos--; fip=tif.tif_fieldinfo[pos]; if(fip.field_type==dt) return tif.tif_foundfield=fip; } pos=min+num/2; for(; ; ) // succeding fieldinfos first and exit if found DataType { if(pos==(tif.tif_fieldinfo.Count-1)) break; if(tif.tif_fieldinfo[pos+1].field_tag!=tag) break; pos++; fip=tif.tif_fieldinfo[pos]; if(fip.field_type==dt) return tif.tif_foundfield=fip; } return null; } if(fip.field_tag>tag) return TIFFFindFieldInfoSearch(tif, tag, dt, min, num/2); return TIFFFindFieldInfoSearch(tif, tag, dt, min+num/2+1, num-(num/2+1)); }
static TIFFFieldInfo TIFFFindFieldInfoByName(TIFF tif, string field_name, TIFFDataType dt) { if(tif.tif_foundfield!=null&&tif.tif_foundfield.field_name==field_name&& (dt==TIFFDataType.TIFF_ANY||dt==tif.tif_foundfield.field_type)) return tif.tif_foundfield; // If we are invoked with no field information, then just return. if(tif.tif_fieldinfo==null||tif.tif_fieldinfo.Count==0) return null; foreach(TIFFFieldInfo fip in tif.tif_fieldinfo) { if(fip.field_name==field_name&&(dt==TIFFDataType.TIFF_ANY||fip.field_type==dt)) return tif.tif_foundfield=fip; } return null; }
// Return size of TIFFDataType in bytes. // // XXX: We need a separate function to determine the space needed // to store the value. For TIFF_RATIONAL values TIFFDataWidth() returns 8, // but we use 4-byte float to represent rationals. static int TIFFDataSize(TIFFDataType type) { switch(type) { case TIFFDataType.TIFF_BYTE: case TIFFDataType.TIFF_ASCII: case TIFFDataType.TIFF_SBYTE: case TIFFDataType.TIFF_UNDEFINED: return 1; case TIFFDataType.TIFF_SHORT: case TIFFDataType.TIFF_SSHORT: return 2; case TIFFDataType.TIFF_LONG: case TIFFDataType.TIFF_SLONG: case TIFFDataType.TIFF_FLOAT: case TIFFDataType.TIFF_IFD: case TIFFDataType.TIFF_RATIONAL: case TIFFDataType.TIFF_SRATIONAL: return 4; case TIFFDataType.TIFF_DOUBLE: return 8; default: return 0; } }
static TIFFFieldInfo TIFFFindFieldInfo(TIFF tif, TIFFTAG tag, TIFFDataType dt) { if(tif.tif_foundfield!=null&&tif.tif_foundfield.field_tag==tag&& (dt==TIFFDataType.TIFF_ANY||dt==tif.tif_foundfield.field_type)) return tif.tif_foundfield; // If we are invoked with no field information, then just return. if(tif.tif_fieldinfo==null||tif.tif_fieldinfo.Count==0) return null; #if !USE_TIFFFindFieldInfoSearch foreach(TIFFFieldInfo fip in tif.tif_fieldinfo) { if(fip.field_tag==tag&&(dt==TIFFDataType.TIFF_ANY||fip.field_type==dt)) return tif.tif_foundfield=fip; } return null; #else return TIFFFindFieldInfoSearch(tif, tag, dt, 0, tif.tif_fieldinfo.Count); #endif }
// Return size of TIFFDataType in bytes public static int TIFFDataWidth(TIFFDataType type) { switch(type) { case TIFFDataType.TIFF_NOTYPE: case TIFFDataType.TIFF_BYTE: case TIFFDataType.TIFF_ASCII: case TIFFDataType.TIFF_SBYTE: case TIFFDataType.TIFF_UNDEFINED: return 1; case TIFFDataType.TIFF_SHORT: case TIFFDataType.TIFF_SSHORT: return 2; case TIFFDataType.TIFF_LONG: case TIFFDataType.TIFF_SLONG: case TIFFDataType.TIFF_FLOAT: case TIFFDataType.TIFF_IFD: return 4; case TIFFDataType.TIFF_RATIONAL: case TIFFDataType.TIFF_SRATIONAL: case TIFFDataType.TIFF_DOUBLE: return 8; default: return 0; // will return 0 for unknown types } }
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; }
static bool Fax3VSetField(TIFF tif, TIFFTAG tag, TIFFDataType dt, object[] ap) { Fax3BaseState sp=tif.tif_data as Fax3BaseState; #if DEBUG if(sp==null) throw new Exception("sp==null"); if(sp.vsetparent==null) throw new Exception("sp.vsetparent==null"); #endif switch(tag) { case TIFFTAG.FAXMODE: sp.mode=(FAXMODE)__GetAsInt(ap, 0); return true; // NB: pseudo tag case TIFFTAG.GROUP3OPTIONS: // XXX: avoid reading options if compression mismatches. if(tif.tif_dir.td_compression==COMPRESSION.CCITTFAX3) sp.groupoptions=(GROUP3OPT)__GetAsUint(ap, 0); break; case TIFFTAG.GROUP4OPTIONS: // XXX: avoid reading options if compression mismatches. if(tif.tif_dir.td_compression==COMPRESSION.CCITTFAX4) sp.groupoptions=(GROUP3OPT)__GetAsUint(ap, 0); break; case TIFFTAG.BADFAXLINES: sp.badfaxlines=__GetAsUint(ap, 0); break; case TIFFTAG.CLEANFAXDATA: sp.cleanfaxdata=(CLEANFAXDATA)__GetAsUshort(ap, 0); break; case TIFFTAG.CONSECUTIVEBADFAXLINES: sp.badfaxrun=__GetAsUint(ap, 0); break; case TIFFTAG.FAXRECVPARAMS: sp.recvparams=__GetAsUint(ap, 0); break; case TIFFTAG.FAXSUBADDRESS: sp.subaddress=ap[0] as string; break; case TIFFTAG.FAXRECVTIME: sp.recvtime=__GetAsUint(ap, 0); break; case TIFFTAG.FAXDCS: sp.faxdcs=ap[0] as string; break; default: return sp.vsetparent(tif, tag, dt, ap); } TIFFFieldInfo fip=TIFFFieldWithTag(tif, tag); if(fip!=null) TIFFSetFieldBit(tif, fip.field_bit); else return false; tif.tif_flags|=TIF_FLAGS.TIFF_DIRTYDIRECT; return true; }
public short field_writecount; // write count/TIFF_VARIABLE #endregion Fields #region Constructors public TIFFFieldInfo(TIFFTAG field_tag, short field_readcount, short field_writecount, TIFFDataType field_type, FIELD field_bit, bool field_oktochange, bool field_passcount, string field_name) { this.field_tag=field_tag; this.field_readcount=field_readcount; this.field_writecount=field_writecount; this.field_type=field_type; this.field_bit=field_bit; this.field_oktochange=field_oktochange; this.field_passcount=field_passcount; this.field_name=field_name; }
// Setup a directory entry of an array of RATIONAL // or SRATIONAL and write the associated indirect values. static bool TIFFWriteRational(TIFF tif, TIFFDataType type, TIFFTAG tag, TIFFDirEntry dir, double fv) { dir.tdir_tag=(ushort)tag; dir.tdir_type=(ushort)type; dir.tdir_count=1; byte[] t=null; try { t=new byte[8]; } catch { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "No space to write RATIONAL array"); return false; } int sign=1; uint den=1; if(fv<0) { if(type==TIFFDataType.TIFF_RATIONAL) { TIFFWarningExt(tif.tif_clientdata, tif.tif_name, "\"{0}\": Information lost writing value ({1}) as (unsigned) RATIONAL", TIFFFieldWithTag(tif, tag).field_name, fv); fv=0; } else { fv=-fv; sign=-1; } } if(fv>0) { while(fv<(1<<(31-3))&&den<(1<<(31-3))) { fv*=1<<3; den*=1<<3; } } BitConverter.GetBytes((uint)(sign*(fv+0.5))).CopyTo(t, 0); BitConverter.GetBytes(den).CopyTo(t, 4); return TIFFWriteData(tif, dir, t); }