private void ShortFilter(ShortLookupTable lookup, Raster src, WritableRaster dst, int width, int height, int numBands) { int band; int[] srcPix = null; // Find the ref to the table and the offset short[][] table = lookup.Table; int offset = lookup.Offset; int tidx; int step = 1; // Check if it is one lookup applied to all bands if (table.Length == 1) { step = 0; } int x = 0; int y = 0; int index; int maxShort = (1 << 16) - 1; // Loop through the data for (y = 0; y < height; y++) { tidx = 0; for (band = 0; band < numBands; band++, tidx += step) { // Find data for this band, scanline srcPix = src.GetSamples(0, y, width, 1, band, srcPix); for (x = 0; x < width; x++) { index = srcPix[x] - offset; if (index < 0 || index > maxShort) { throw new IllegalArgumentException("index out of range " + index + " x is " + x + "srcPix[x]=" + srcPix[x] + " offset=" + offset); } // Do the lookup srcPix[x] = table[tidx][index]; } // Put it back dst.SetSamples(0, y, width, 1, band, srcPix); } } }
/// <summary> /// Rescales the pixel data in the source Raster. /// If the destination Raster is null, a new Raster will be created. /// The source and destination must have the same number of bands. /// Otherwise, an IllegalArgumentException is thrown. /// Note that the number of scaling factors/offsets in this object must /// meet the restrictions stated in the class comments above. /// Otherwise, an IllegalArgumentException is thrown. </summary> /// <param name="src"> the <code>Raster</code> to be filtered </param> /// <param name="dst"> the destination for the filtering operation /// or <code>null</code> </param> /// <returns> the filtered <code>WritableRaster</code>. </returns> /// <exception cref="IllegalArgumentException"> if <code>src</code> and /// <code>dst</code> do not have the same number of bands, /// or if the number of scaling factors and offsets in this /// <code>RescaleOp</code> do not meet the requirements /// stated in the class comments. </exception> public WritableRaster Filter(Raster src, WritableRaster dst) { int numBands = src.NumBands; int width = src.Width; int height = src.Height; int[] srcPix = null; int step = 0; int tidx = 0; // Create a new destination Raster, if needed if (dst == null) { dst = CreateCompatibleDestRaster(src); } else if (height != dst.Height || width != dst.Width) { throw new IllegalArgumentException("Width or height of Rasters do not " + "match"); } else if (numBands != dst.NumBands) { // Make sure that the number of bands are equal throw new IllegalArgumentException("Number of bands in src " + numBands + " does not equal number of bands in dest " + dst.NumBands); } // Make sure that the arrays match // Make sure that the low/high/constant arrays match if (Length != 1 && Length != src.NumBands) { throw new IllegalArgumentException("Number of scaling constants " + "does not equal the number of" + " of bands in the src raster"); } // // Try for a native raster rescale first // if (ImagingLib.filter(this, src, dst) != null) { return(dst); } // // Native raster rescale failed. // Try to see if a lookup operation can be used // if (CanUseLookup(src, dst)) { int srcNgray = (1 << SrcNbits); int dstNgray = (1 << DstNbits); if (dstNgray == 256) { ByteLookupTable lut = CreateByteLut(ScaleFactors, Offsets, numBands, srcNgray); LookupOp op = new LookupOp(lut, Hints); op.Filter(src, dst); } else { ShortLookupTable lut = CreateShortLut(ScaleFactors, Offsets, numBands, srcNgray); LookupOp op = new LookupOp(lut, Hints); op.Filter(src, dst); } } else { // // Fall back to the slow code // if (Length > 1) { step = 1; } int sminX = src.MinX; int sY = src.MinY; int dminX = dst.MinX; int dY = dst.MinY; int sX; int dX; // // Determine bits per band to determine maxval for clamps. // The min is assumed to be zero. // REMIND: This must change if we ever support signed data types. // int nbits; int[] dstMax = new int[numBands]; int[] dstMask = new int[numBands]; SampleModel dstSM = dst.SampleModel; for (int z = 0; z < numBands; z++) { nbits = dstSM.GetSampleSize(z); dstMax[z] = (1 << nbits) - 1; dstMask[z] = ~(dstMax[z]); } int val; for (int y = 0; y < height; y++, sY++, dY++) { dX = dminX; sX = sminX; for (int x = 0; x < width; x++, sX++, dX++) { // Get data for all bands at this x,y position srcPix = src.GetPixel(sX, sY, srcPix); tidx = 0; for (int z = 0; z < numBands; z++, tidx += step) { val = (int)(srcPix[z] * ScaleFactors[tidx] + Offsets[tidx]); // Clamp if ((val & dstMask[z]) != 0) { if (val < 0) { val = 0; } else { val = dstMax[z]; } } srcPix[z] = val; } // Put it back for all bands dst.SetPixel(dX, dY, srcPix); } } } return(dst); }