HF_VAL image_height_at(const ImageData *image, int x, int y) { // TODO ALPHA - handling of premultiplied vs. non-premultiplied alpha needs to be considered RGBColour colour; // for 8-bit indexed images, use the index (scaled to match short int range) if (image->data->IsIndexed()) return ((HF_VAL)image->data->GetIndexedValue(x, y) * 256); // TODO FIXME - should be *257 to get a max value of 255*257 = 65535 /* [JG-2013]: do not change 256 for 257, due to backward compatibility with all versions up to 3.6 * it's a shame to not being able to cover the full range when using indexed image, but * it was like that for a very very long time (since the introduction of height field in povray) */ // for greyscale images, use the float greyscale value (scaled to match short int range) if (image->data->IsGrayscale()) return ((HF_VAL) (image->data->GetGrayValue(x, y) * 65535.0f)); image->data->GetRGBValue(x, y, colour); // TODO - what about alpha premultiplication? // for images with high bit depth (>8 bit per color channel), use the float greyscale value (scaled to match short int range) if (image->data->GetMaxIntValue() > 255) return ((HF_VAL) (colour.Greyscale() * 65535.0f)); // for images with low bit depth (<=8 bit per color channel), compose from red (high byte) and green (low byte) channel. return ((HF_VAL) ((colour.red() * 256.0 + colour.green()) * 255.0)); // [JG-2013] : the high byte / low byte is (r *255) * 256 + (g*255) , which is factored as (r*256+g)*255 (was issue flyspray #308) }
void GetEncodedRGBValue(const Image* img, unsigned int x, unsigned int y, const GammaCurvePtr& g, RGBColour& col) { if (!img->IsPremultiplied() && img->HasTransparency()) { // data has transparency and is stored non-premultiplied; precompose against a black background float fAlpha; img->GetRGBAValue(x, y, col.red(), col.green(), col.blue(), fAlpha); AlphaPremultiply(col, fAlpha); } else { // no need to worry about premultiplication img->GetRGBValue(x, y, col.red(), col.green(), col.blue()); } col.red() = GammaCurve::Encode(g,col.red()); col.green() = GammaCurve::Encode(g,col.green()); col.blue() = GammaCurve::Encode(g,col.blue()); }
void Evaluate_Density_Pigment(const PIGMENT *pigm, const Vector3d& p, RGBColour& c, TraceThreadData *ttd) { Colour lc; c.set(1.0); while(pigm != NULL) { lc.clear(); Compute_Pigment(lc, pigm, *p, NULL, NULL, ttd); c.red() *= lc.red(); c.green() *= lc.green(); c.blue() *= lc.blue(); pigm = reinterpret_cast<const PIGMENT *>(pigm->Next); } }
bool ot_read_file(OT_NODE **root, IStream *fd, const OT_READ_PARAM* param, OT_READ_INFO* info) { bool retval, got_eof; int line_num = 0; int tempdepth, tx, ty, tz; int goodreads = 0; int count; bool goodparse = true; DBL brightness; OT_BLOCK bl; OT_BLOCK *new_block; OT_ID id; char normal_string[30], to_nearest_string[30]; char line[101]; memset(&bl, 0, sizeof(OT_BLOCK)); if ( fd != NULL ) { info->Gather_Total.Clear(); info->Gather_Total_Count = 0; while (!(got_eof = fd->getline (line, 99).eof ()) && goodparse) { switch ( line[0] ) { case 'B': // the file contains the old radiosity_brightness value { if ( sscanf(line, "B%lf\n", &brightness) == 1 ) { info->Brightness = brightness; } break; } case 'P': // the file made it to the point that the Preview was done { info->FirstRadiosityPass = true; break; } case 'C': { #if (NUM_COLOUR_CHANNELS == 3) RGBColour tempCol; count = sscanf(line, "C%d %lf %lf %lf %s %f %f %f %f %f %s\n", // tw &tempdepth, // since you can't scan a short &bl.Point[X], &bl.Point[Y], &bl.Point[Z], normal_string, &tempCol.red(), &tempCol.green(), &tempCol.blue(), &bl.Harmonic_Mean_Distance, &bl.Nearest_Distance, to_nearest_string ); bl.Illuminance = ToMathColour(tempCol); #else #error TODO! #endif // TODO FIXME - read Quality and Brilliance if ( count == 11 ) { bl.Bounce_Depth = (short)tempdepth - 1; // normals aren't very critical for direction precision, so they are packed sscanf(normal_string, "%02x%02x%02x", &tx, &ty, &tz); bl.S_Normal[X] = ((double)tx * (1./ 254.))*2.-1.; bl.S_Normal[Y] = ((double)ty * (1./ 254.))*2.-1.; bl.S_Normal[Z] = ((double)tz * (1./ 254.))*2.-1.; bl.S_Normal.normalize(); sscanf(to_nearest_string, "%02x%02x%02x", &tx, &ty, &tz); bl.To_Nearest_Surface[X] = ((double)tx * (1./ 254.))*2.-1.; bl.To_Nearest_Surface[Y] = ((double)ty * (1./ 254.))*2.-1.; bl.To_Nearest_Surface[Z] = ((double)tz * (1./ 254.))*2.-1.; bl.To_Nearest_Surface.normalize(); line_num++; new_block = reinterpret_cast<OT_BLOCK *>(POV_MALLOC(sizeof (OT_BLOCK), "octree node from file")); if ( new_block != NULL ) { POV_MEMCPY(new_block, &bl, sizeof (OT_BLOCK)); ot_index_sphere(bl.Point, bl.Harmonic_Mean_Distance * param->RealErrorBound, &id); ot_ins(root, new_block, &id); goodreads++; } else { goodparse = false; // allocation error, better stop now } } break; } default: { // wrong leading character on line, just try again on next line } } // end switch } // end while-reading loop if ( !got_eof || !goodparse ) { ;// TODO MESSAGE PossibleError("Cannot process radiosity cache file at line %d.", (int)line_num); retval = false; } else { if ( goodreads > 0 ) ;// TODO MESSAGE Debug_Info("Reloaded %d values from radiosity cache file.\n", goodreads); else ;// TODO MESSAGE PossibleError("Unable to read any values from the radiosity cache file."); retval = true; } } else { retval = false; } return retval; }
void SetEncodedRGBValue(Image* img, unsigned int x, unsigned int y, const GammaCurvePtr& g, const RGBColour& col) { img->SetRGBValue(x, y, GammaCurve::Decode(g,col.red()), GammaCurve::Decode(g,col.green()), GammaCurve::Decode(g,col.blue())); }
void AlphaUnPremultiply(RGBColour& colour, float fAlpha) { AlphaUnPremultiply(colour.red(), colour.green(), colour.blue(), fAlpha); }
DblRGBColour SubsurfaceInterior::GetReducedAlbedo(const RGBColour& diffuseReflectance) const { return DblRGBColour(((const PrecomputedReducedAlbedo&)precomputedReducedAlbedo)(diffuseReflectance.red()), ((const PrecomputedReducedAlbedo&)precomputedReducedAlbedo)(diffuseReflectance.green()), ((const PrecomputedReducedAlbedo&)precomputedReducedAlbedo)(diffuseReflectance.blue())); }