DBL image_pattern(const Vector3d& EPoint, const BasicPattern* pPattern) { DBL xcoor = 0.0, ycoor = 0.0; int index = -1; RGBFTColour colour; const ImageData *image = dynamic_cast<const ImagePatternImpl*>(pPattern)->pImage; DBL Value; colour.Clear(); // going to have to change this // need to know if bump point is off of image for all 3 points if(map_pos(EPoint, pPattern, &xcoor, &ycoor)) return 0.0; else image_colour_at(image, xcoor, ycoor, colour, &index); // TODO ALPHA - we should decide whether we prefer premultiplied or non-premultiplied alpha if((index == -1) || image->Use) { if(image->Use == USE_ALPHA) { // use alpha channel or red channel if(image->data->HasTransparency() == true) Value = colour.transm(); else Value = colour.red(); // otherwise, just use the red channel } else // use grey-scaled version of the color Value = colour.Greyscale(); } else Value = index / 255.0; if(Value < 0) Value = 0; else if(Value > 1.0) Value = 1.0; return Value; }
static void InterpolateBicubic(const ImageData *image, DBL xcoor, DBL ycoor, RGBFTColour& colour, int *index, bool premul) { int iycoor, ixcoor; int cornerIndex; RGBFTColour cornerColour; DBL factor; DBL factorsX[4]; DBL factorsY[4]; xcoor += 0.5; ycoor += 0.5; iycoor = (int)ycoor; ixcoor = (int)xcoor; cubic(factorsX, xcoor); cubic(factorsY, ycoor); // We're using double precision for the colors here to avoid higher-than-1.0 results due to rounding errors, // which would otherwise lead to stray dot artifacts when clamped to [0..1] range for a color_map or similar. // (Note that strictly speaking we don't avoid such rounding errors, but rather make them small enough that // subsequent rounding to single precision will take care of them.) // (Note that bicubic interpolation may still give values outside the range [0..1] at high-contrast edges; // this is an inherent property of this interpolation method, and is therefore accepted here.) PreciseRGBFTColour tempColour; DBL tempIndex = 0; for (int i = 0; i < 4; i ++) { for (int j = 0; j < 4; j ++) { cornerColour.Clear(); no_interpolation(image, (DBL)ixcoor + i-2, (DBL)iycoor + j-2, cornerColour, &cornerIndex, premul); factor = factorsX[i] * factorsY[j]; tempColour += PreciseRGBFTColour(cornerColour) * factor; tempIndex += cornerIndex * factor; } } colour = RGBFTColour(tempColour); *index = (int)tempIndex; }